Friday, October 26, 2007

Ayende is the man. Seriously.

Today, he released Rhino Mocks 3.3 to great fanfare.

If there wasn't great fanfare, there should be. My favorite new feature - mocking objects that inherit from MarshalByRefObject. You might be asking yourself, why does this matter? Doesn't that only apply to remoting? Well, yes, sort of. The thing is, a huge number of the built-in classes in the CLR support this remoting infrastructure. You know the ones I'm talking about - the built-in classes that are hard to mock and test.

At least they didn't let you mock them out until today. Here's an example of something that might have been harder to test before today:

[TestFixture]
public class Tests
{
    [Test]
    public void TestingCoolRhinoMocksStuff()
    {
        MockRepository mocks = new MockRepository();

        Process p = mocks.CreateMock<Process>();
 
        using (mocks.Record())
        {
            Expect.Call(p.Responding).Return(false);
        }
 
        using (mocks.Playback())
        {
            Assert.IsFalse(p.Responding);
        }
    }
}

Yeah, I'm mocking System.Diagnostics.Process. Sweet.

Take a look in Reflector and you'll find out just how many objects actually inherit from MarshalByRefObject. I think you'll be quite surprised.

Thanks Ayende!

posted on Friday, October 26, 2007 10:56:32 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, October 18, 2007

I was reading through my feeds this morning and came across this gem of a paragraph:

Manual testing is immoral. Not only is it high stress, tedious, and error prone; it’s just wrong to turn humans into machines. If you can write a script for a test procedure, then you can write a program to execute that procedure. That program will be cheaper, faster, and more accurate than a human, and will free the human to do what humans to best: create!

The paragraph is actually an aside to the rest of the post, too! Go read the entire TDD post in context at the ObjectMentor blogs.

posted on Thursday, October 18, 2007 7:15:18 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, October 17, 2007

My wife and I got back from Nashville last night and we had a great time. While she went around shopping at garage sales and hanging out with family, I got to spend some time with some great developers at devLink. The conference was incredible. I'm still amazed that they were able to do so much with only $50, but no complaints here :-)

Here are a few of the high points from the conference:

Keith Elder had a great presentation on the Enterprise Library. It was especially good to hear from someone who is using EntLib successfully from a WinForms perspective. I also got to talk to him a little after his presentation on some of their techniques for storing configuration across smart client applications.

Josh Holmes is a great speaker. I'm not at all surprised that he is one of the hosts for the new Code To Live! show. He is clearly passionate about the coding craft. He shared some great information about the DLR with us.

I got to hear Dave Laribee talk about Domain Driven Design, which was great. I also spoke with him about ALT.NET and Microsoft's upcoming MVC framework for ASP.NET. He told me that there are already plans for the next ALT.NET conference which is great news.

Ron Jacobs had the closing keynote on Saturday evening that covered Test Driven Development and the Model View Presenter architecture. It was a great presentation and it was encouraging to have Microsoft's presence there encouraging and pushing TDD.

One of the best things about the conference was how approachable everyone was. I got to meet a lot of great people and I even got the change to give Colin grief about winning the blogging contest (not that you can give someone much grief about winning an Xbox 360). My only complaint was that I wasn't able to attend some of the other presentations where there were schedule conflicts.

All in all, the conference was great. The staff and the presenters all did a great job.

posted on Wednesday, October 17, 2007 11:57:29 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, October 10, 2007

I'm getting ready to start the drive to Nashville tonight for DevLink 2007. It will be my first real conference to attend and I'm really excited about it. It will also be fun to get to hang out in Nashville. If you'll be at the conference, look me up!

I know a few of you who are planning on going so you have no excuses to not say hi when you're there! :-)

posted on Wednesday, October 10, 2007 3:45:25 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, October 03, 2007

image

*sigh*

posted on Wednesday, October 03, 2007 8:44:23 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, September 28, 2007

One of the banes of my existence (okay, not that bad but fun to say) is supporting Windows 2000 at work. Yes, there are still Win2K machines out there - not many, but enough to make a difference. One problem is that .NET 3.0/3.5 isn't supported on Win2K, so we're limited in what we can do, at least on the client-side. Another problem is just strange issues with the framework. 99% of the stuff we write works great, but there are a few things that don't.

Here is one that caused mass confusion recently.

Check out the code for this incredibly simple console application that I wrote:

Module Module1
 
    Sub Main()
 
        Console.WriteLine(">>Environment.CommandLine = {0}", Environment.CommandLine)
        Console.WriteLine(">>Environment.GetCommandLineArgs()(0) = {0}", Environment.GetCommandLineArgs()(0))
 
        Dim commandLineFileName As String = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()(0))
        Console.WriteLine(">>commandLineFileName = {0}", commandLineFileName)
 
        Console.WriteLine(">>ProcessName = {0}", Process.GetCurrentProcess.ProcessName)
 
        Console.WriteLine("Press enter to continue....")
        Console.ReadLine()
 
    End Sub
 
End Module

What would you expect the output to be?

Here's what it does on Windows XP:

>>Environment.CommandLine = ConsoleApplication1.exe
>>Environment.GetCommandLineArgs()(0) = ConsoleApplication1.exe
>>commandLineFileName = ConsoleApplication1.exe
>>ProcessName = ConsoleApplication1
Press enter to continue.... 

On Windows 2000, it does the same thing. Super.

Let's change the name of the executable to ThisIsALongNameForAnExe.exe and run it again.

>>Environment.CommandLine = ThisIsALongNameForAnExe.exe
>>Environment.GetCommandLineArgs()(0) = ThisIsALongNameForAnExe.exe
>>commandLineFileName = ThisIsALongNameForAnExe.exe
>>ProcessName = ThisIsALongNameForAnExe
Press enter to continue.... 

Once again, Windows 2000 behaves the same way. Great.

Let's try one more thing. Let's change the name of the executable to This.Is.A.Long.Name.For.An.Exe.exe and run it one last time.

Windows XP looks like this:

>>Environment.CommandLine = This.Is.A.Long.Name.For.An.Exe.exe
>>Environment.GetCommandLineArgs()(0) = This.Is.A.Long.Name.For.An.Exe.exe
>>commandLineFileName = This.Is.A.Long.Name.For.An.Exe.exe
>>ProcessName = This.Is.A.Long.Name.For.An.Exe
Press enter to continue.... 

However, Windows 2000 looks like this:

>>Environment.CommandLine = This.Is.A.Long.Name.For.An.Exe.exe
>>Environment.GetCommandLineArgs()(0) = This.Is.A.Long.Name.For.An.Exe.exe
>>commandLineFileName = This.Is.A.Long.Name.For.An.Exe.exe
>>ProcessName = This.Is.A.Long
Press enter to continue.... 

Can you tell the difference? System.Diagnostics.Process.ProcessName is truncated when running on Win2K. The only thing I can tell is that the periods in the process name throw it off. Granted, hopefully you don't have anything secure relying on the name of your process (cough, rename, cough), but it still came across as very unexpected.

Note - the results can be different depending on how you actually execute the program. The command line and command line arguments are literally what was typed when the program is executed.

posted on Friday, September 28, 2007 1:21:13 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, September 26, 2007

I am a moron.

Like so many of the millions of other Halo fans, I preordered my copy of Halo 3 literally months ago. I've been waiting impatiently for months (years?) for it to release and now it is out.

And I haven't got to play it yet.

Because it still hasn't shipped to my door.

I should have chosen in-store pickup.

*sigh*

posted on Wednesday, September 26, 2007 8:05:44 PM (Central Standard Time, UTC-06:00)  #    Comments [0]

Yesterday, I had a somewhat strange experience. I was helping someone with a problem they were having and, almost as a side note, this individual thought he would share some code with me that he was particularly proud of. He even prefaced the story with the "not to brag or anything" phrase. He had written some custom code to help text boxes grow or shrink depending on how the user resized the window. If you know anything about WinForms, you'll know that some simple anchoring techniques and good use of the SplitContainer will solve this problem for you - please, please, please don't go writing custom mathematical equations when the framework can take care of it for you.

At the time, I was pretty annoyed with it, because this individual was bragging about something that I considered "the wrong way to do it." In retrospect, this probably was the wrong response. Why? Because he was proud of some of the code he had written. He actually cared about it enough to not just treat it as something to toss off on to someone else when he moved to the next project.

The projects that have turned out best that I've worked on the ones where I was really proud of the code. That doesn't mean I did it the right way. I'm thinking of one example where I wrote this crazy elaborate dynamic menu system in JavaScript. It even worked in both Firefox and Internet Explorer. It had a full blown object model and made use of closures and more - it was great. Here's a complete example of usage of the menu:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title>clsNavBar</title>
      <script language="JavaScript" src="clsMenu.js"></script>
      <link href="styles.css" rel="stylesheet" type="text/css">
   </head>
 
   <body>
      <script language="JavaScript">
        var nav = new clsMenu();
        nav.setContainer(document.body);
        nav.setXMLUrl("NavBar.xml");
        //nav.setHorizontal(false)
        nav.buildMenu();
      </script>
   </body>
</html>

It had one problem. Maintenance. Maintenance on the system will be nigh impossible for the next guy. From the very beginning, I should have used CSS for the entire menu structure. When and if someone ever decides to change the way the menus look, well... good luck. However, it was still a good experience. I learned more about the inner workings of JavaScript from working with that than I did from any blog post or book I've ever looked at. I would have never learned what exactly 'this' references in JavaScript without that example (see this post on JavaScript gotchas and refer to the section on 'this').

In all of this, I have learned to be very careful of the code I'm proud of. Inevitably, if you're growing as a developer by "sucking less every year," you're not going to be too proud of your code in a year or two anyway.

Do you have any code you're particularly proud of? If it turned out to be the "wrong way to do it" but you learned a lot from the experience, you get bonus points.

posted on Wednesday, September 26, 2007 7:17:19 AM (Central Standard Time, UTC-06:00)  #    Comments [2]