Nerdy tidbits from my life as a software engineer

Thursday, February 21, 2008

Unit Testing in VS2008 With Mock Frameworks

As a big believer in test driven development, I spent some time today fiddling around with Visual Studio 2008's new unit testing features. Boy is that a nice addition! As much as I have been a fan of testdriven.net, I am now convinced that there is no longer any point in using the plugin. The Visual Studio integration makes using NUnit obsolete as well. The whole process is nicely and conveniently built into the IDE, and it is a very welcome addition indeed. The tools are infinitely better and nicer: debugging tests is trivial, grouping tests into packages is easy, and managing configuration items is equally easy.

I am also a big believer in mock frameworks. How do you expect to test functions without separating dependencies? I've worked with unit tests that are completely broken and useless because they never abstracted the data they were testing against. What good is a test that needs to be updated every month or so? Without separating dependencies, unit tests turn into gigantic messes when something fails - because you'll end up with 40 failed tests and no clear indication of where the break occurred. A nicely mocked up suit of unit tests makes it clear where something breaks, because instead of having 40 broken tests you'll have 1. It also allows you to forget about external dependencies such as databases, web services, or text files.

The API that I have used extensively, and I think a lot of other people have adopted as well, is Rhino Mocks. This superior framework is difficult to use at first, but is incredibly powerful. The greatest thing about Rhino Mocks is that it is strongly typed, which means that all of the Visual Studio refactoring tools work with your unit tests. Without this feature, managing giant suits of tests would be infeasible. While wasting time looking through the MSDN's RSS blog today, however, I ran across an entry that pointed me towards a new framework called Moq. So, naturally, I downloaded it and started to fool around with it. It is tough to say right now which one I prefer, since they both have their advantages. The Rhino API is something I am familiar with, and is flexible enough to do whatever you want with it. Moq, on the other hand, has a very 3.5-ish feel to it, since it draws on Linq expressions and makes heavy use of lambda functions.

But enough chit-chat. Let's look at an example that we can compare and contrast:

/// <summary>
/// This class has methods that we will use to run some tests on.
/// </summary>
public class TestClass
{
    /// <summary>
    /// Gets / sets the aggregated class.
    /// </summary>
    public AggregatedClass AggregatedClass
    {
        get;
        set;
    }

    /// <summary>
    /// Call the aggregated class.
    /// </summary>
    /// <param name="x"></param>
    /// <returns></returns>
    public int Halve(int x)
    {
        return this.AggregatedClass.Halve(x);
    }

}

...

/// <summary>
/// A class that is aggregated by another class.
/// </summary>
public class AggregatedClass
{
    /// <summary>
    /// Divides a number by 2.
    /// </summary>
    /// <param name="x">The number to divide.</param>
    /// <returns>Half of the number inputted.</returns>
    public virtual int Halve(int x)
    {
        return x / 2;
    }

}

Using Rhino Mocks, you would mock the AggregatedClass and test TestClass as follows:

/// <summary>
/// Test using Rhino Mocks API.
/// </summary>
[TestMethod]
public void TestHalve1()
{
    MockRepository mocks = new MockRepository();
    AggregatedClass aggregatedClass = mocks.CreateMock<AggregatedClass>();

    mocks.BackToRecordAll();
    Expect.Call(aggregatedClass.Halve(12)).Return(6);
    mocks.ReplayAll();

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass;
    Assert.AreEqual(6, testClass.Halve(12));
    mocks.VerifyAll();

}

Here is the Moq equivalent:

/// <summary>
/// Test using Moq API.
/// </summary>
[TestMethod]
public void TestHalve2()
{
    var aggregatedClass = new Mock<AggregatedClass>(MockBehavior.Strict);
    aggregatedClass.Expect(x => x.Halve(12)).Returns(6);

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass.Object;
    Assert.AreEqual<int>(6, testClass.Halve(12));
    
    aggregatedClass.VerifyAll();

}

In practice, both of these API's do the same thing. But there are a few key differences between the two. The first is that Rhino is very 'Mock-Centric', meaning that everything goes through the MockRepository object. All verifications of expectations, recording, etc., go through the MockRepository. Moq, in contrast, allows mocks to be verified individually. In practice, I doubt this would be the way I would want to go since it is usually necessary to group mock objects into a single sequence of calls that need to be verified in unison. Fortunately, there is a way to do this using the Moq framework:

/// <summary>
/// Test using Moq API.
/// </summary>
[TestMethod]
public void TestHalve2()
{
    MockFactory factory = new MockFactory(MockBehavior.Strict);
    var aggregatedClass = factory.Create<AggregatedClass>();
    aggregatedClass.Expect(x => x.Halve(12)).Returns(6);

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass.Object;
    Assert.AreEqual(6, testClass.Halve(12));

    factory.VerifyAll();

}

One thing that is unfortunate about this approach is that the behavior parameter is defined in the MockFactory class, and cannot be customized in any other location (it cannot be set via the Create method). The Rhino Mocks API supports a very essential function called PartialMock, which allows calls to go to the default implementation if no expectation is set on them. This means that Moq has an all-or-nothing approach to setting the behavior of the mocks that it creates. Of course, one can get around this by creating a mix of mock objects using a combination of techniques from both of these examples, but it becomes difficult since the global VerifyAll() call won't work for them. Partial mocks are critical when dealing with abstract classes with abstract methods. 

One really nice thing about Moq, however, is how it allows you to verify arguments. Take an example where I want to test that Halve is called with a positive number. How is that done with Rhino mocks? Here's one way:

private delegate bool CallbackDel(int x);


/// <summary>
/// Test using Rhino Mocks API.
/// </summary>
[TestMethod]
public void TestHalve1()
{
    MockRepository mocks = new MockRepository();
    AggregatedClass aggregatedClass = mocks.CreateMock<AggregatedClass>();

    mocks.BackToRecordAll();
    Expect.Call(aggregatedClass.Halve(12)).Return(6);

    LastCall.Callback((CallbackDel)((int x) =>
    {
        return x > 0;
    }));

    mocks.ReplayAll();

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass;
    Assert.AreEqual(6, testClass.Halve(12));
    mocks.VerifyAll();

}

A more elegant solution, however, would be to use constraints:

/// <summary>
/// Test using Rhino Mocks API.
/// </summary>
[TestMethod]
public void TestHalve1()
{
    MockRepository mocks = new MockRepository();
    AggregatedClass aggregatedClass = mocks.CreateMock<AggregatedClass>();

    mocks.BackToRecordAll();
    Expect.Call(aggregatedClass.Halve(12)).IgnoreArguments().Return(6);
    LastCall.Constraints(Is.GreaterThan(0));
    mocks.ReplayAll();

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass;
    Assert.AreEqual(6, testClass.Halve(6));
    mocks.VerifyAll();

}

One nice thing about Moq is that it makes checking arguments a lot easier. Here's an example of how that works:

/// <summary>
/// Test using Moq API.
/// </summary>
[TestMethod]
public void TestHalve2()
{
    MockFactory factory = new MockFactory(MockBehavior.Strict);
    var aggregatedClass = factory.Create<AggregatedClass>();
    aggregatedClass.Expect(x => x.Halve(It.Is<int>(y => y > 0))).Returns(6);

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass.Object;
    Assert.AreEqual(6, testClass.Halve(12));

    factory.VerifyAll();

}

The great thing about using delegates for value checking is that you can put whatever you want in there. Want to test that y is an even number? Replace

y => y > 0

...with...

y => y % 2 == 0

I think this is a much more sophisticated system than the one used in the Rhino mocks API. Sadly, it appears that there are still a lot of things left to be done. For instance, where are the ordered and unordered calls? MockFactory does not contain them, and there is no way to set a repeating value. For instance, say we want to test the following method:

/// <summary>
/// Quarters a number.
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public virtual int Quarter(int x)
{
    for(int i = 0; i < 10; i++)
    {
        if(i % 2 == 0)
        {
            this.AggregatedClass.Foo(x);
            this.AggregatedClass.Bar(x);
        }
        else
        {
            this.AggregatedClass.Bar(x);
            this.AggregatedClass.Foo(x);                    
        }
    }

    x = this.AggregatedClass.Halve(x);
    return this.AggregatedClass.Halve(x);

}

This is easy with Rhino Mocks:

[TestMethod]
public void TestQuarter()
{
    MockRepository mocks = new MockRepository();
    AggregatedClass aggregatedClass = mocks.CreateMock<AggregatedClass>();

    mocks.BackToRecordAll();
    using(mocks.Ordered())
    {
        using(mocks.Unordered())
        {
            for(int i = 0; i < 10; i++)
            {
                aggregatedClass.Foo(12);
                aggregatedClass.Bar(12);
            }
        }

        Expect.Call(aggregatedClass.Halve(12));
        LastCall.IgnoreArguments().Repeat.Any().Return(3);

    }
    mocks.ReplayAll();

    TestClass testClass = new TestClass();
    testClass.AggregatedClass = aggregatedClass;
    Assert.AreEqual(3, testClass.Quarter(12));
    mocks.VerifyAll();

}

Unfortunately, this is currently not possible with the Moq API. In my mind, this is a pretty serious drawback. The reality is that you need these types of order constraints in order to validate your mock calls. Hopefully, that stuff gets added in the future.

The point is that there are a number of exciting things going on in the world of unit testing, and it's fun to see these API's improve. We'll see where it all ends up in a few years.

Wednesday, February 13, 2008

Comprehension Syntax Mysteries Solved

Thank God for comprehension syntax. After fooling around with the very excellent LinqPad for a while, I have finally started to understand how the compiler translates comprehension syntax into compiled code:

from h in Histories
join u in Users on h.UserID equals u.UserID
join l in Locations on u.LocationID equals l.LocationID
select new {
 History = h,
 Profile = u,
 Location = l
}
Gets translated into this:
Histories
   .Join (
      Users, 
      h => h.UserID, 
      u => u.UserID, 
      (h, u) => 
         new  
         {
            h = h, 
            u = u
         }
   )
   .Join (
      Locations, 
      temp0 => temp0.u.LocationID, 
      l => l.LocationID, 
      (temp0, l) => 
         new  
         {
            History = temp0.h, 
            Profile = temp0.u, 
            Location = l
         }
   )

Are there really people who prefer to write Linq queries the second way over the first way? This seems unimaginable to me. You can't understand a thing that's going on in example number two, and this is a pretty simple query. I mean, the above example is pretty simple. Let's see what happens when we clutter this up with more complicated stuff:

from h in Histories
join u in Users on h.UserID equals u.UserID
join l in Locations on u.LocationID equals l.LocationID
let obj = new {
 h.EventName,
 h.Time,
 u.FirstName,
 u.LastName,
 l.LocationName
}
orderby obj.EventName
group obj by obj.EventName

This understandable sequence turns into the following monster using regular C# syntax:

Histories
   .Join (
      Users, 
      h => h.UserID, 
      u => u.UserID, 
      (h, u) => 
         new  
         {
            h = h, 
            u = u
         }
   )
   .Join (
      Locations, 
      temp0 => temp0.u.LocationID, 
      l => l.LocationID, 
      (temp0, l) => 
         new  
         {
            <>h__TransparentIdentifier0 = temp0, 
            l = l
         }
   )
   .Select (
      temp1 => 
         new  
         {
            <>h__TransparentIdentifier1 = temp1, 
            obj = new  
            {
               EventName = temp1.<>h__TransparentIdentifier0.h.EventName, 
               Time = temp1.<>h__TransparentIdentifier0.h.OccuredTime, 
               FirstName = temp1.<>h__TransparentIdentifier0.u.FirstName, 
               LastName = temp1.<>h__TransparentIdentifier0.u.LastName, 
               LocationName = temp1.l.LocationName
            }
         }
   )
   .OrderBy (temp2 => temp2.obj.EventName)
   .GroupBy (
      temp2 => temp2.obj.EventName, 
      temp2 => temp2.obj
   )

I mean, really. How is the second option preferable to the first? You can't possibly look at that garbage and understand what it's doing. Without this logical translation between examples 1 and 2, Linq wouldn't be all that useful. It's just as complicated as if you went and did all this stuff manually using regular procedural methods.

Monday, February 4, 2008

Getting TreeViewItem's From Data Bound Items

As I reported last time, I've had a lot of trouble figuring out how to find a TreeViewItem that is associated with a particular item that it is data bound to. In particular, in my case, I have a hierarchical data template that is bound to some raw XML data, and I've had quite the time figuring out how to select a particular node on the tree view using the XmlElement that it's bound to as a key to look up the item. Finally, however, I have it figured out:

/// <summary>
/// Scours the hierarchy of tree view items until it finds the tree view item 
/// that is associated with the entered child node of a bookmark.
/// </summary>
/// <param name="treeView">The tree view to search.</param>
/// <param name="childElement">The child element whose TreeViewItem 
/// we want to find</param>
/// <returns>The TreeViewItem that is 
/// associated with childElement, or null.</returns>
public static TreeViewItem GetTreeViewItemForElement(TreeView treeView, XmlElement childElement)
{
    Stack<XmlNode> pathStack = new Stack<XmlNode>();
    pathStack.Push(childElement);

    // Walk down the DOM tree until we find the root bookmark node:
    for(XmlNode parentNode = childElement.ParentNode; 
        parentNode != null;
        parentNode = parentNode.ParentNode)
    {
        if(parentNode.LocalName == "Settings")
        {
            break;
        }

        pathStack.Push(parentNode);

    }

    // This should return the root node:
    ItemContainerGenerator generator = treeView.ItemContainerGenerator;
    XmlNode node = pathStack.Pop();
    TreeViewItem item = generator.ContainerFromItem(node) as TreeViewItem;

    while(pathStack.Count > 0 && item != null)
    {
        // Get the item container generator for this tree node:
        generator = item.ItemContainerGenerator;

        // Pop the node and get the next tree view item:
        node = pathStack.Pop();
        item = generator.ContainerFromItem(node) as TreeViewItem;

    }

    return item;

}

The reason I've been having problems is because each TreeViewItem has it's own ItemContainerGenerator - in other words, there is no global ItemContainerGenerator that can map every databound item for a hierarchical data template! If you need to find the TreeViewItem for some data that is, say, three levels deep, you will need to actually walk the tree from the root on up to the child that you are looking for. In this example, the method will push the parent nodes of the child element into a stack and walk down the DOM until it reaches the root element (the root element that is bound to the tree view is a child node of the root element). Because this root node is bound to the tree view that is passed in, the first call to ContainerFromItem will return the root TreeViewItem. From that point on, all we need to do is walk up the DOM until we reach the child element again - at which point we are finished, since that is what we are looking for.

I will have to revisit the scenario illustrated in the post below. It may or may not be relevant any more since I discovered how to do this.

Friday, February 1, 2008

Well That's....Strange

I've been trying to figure out all week how to programmatically select a tree view item that is generated from a DataTemplate, and have been unable to figure this out until now. But the solution I found doesn't seem to make any sense to me. Oddly enough, this code will work in one place and not another. Let's get to that in a minute:

/// <summary>
/// Not sure why this only works here....
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnBookmarkTreeViewLoaded(object sender, RoutedEventArgs e)
{
    // Select the root bookmark folder.
    ItemContainerGenerator generator = mBookmarkTreeView.ItemContainerGenerator;

    // This is a little trick to get this event to fire one single time.
    ItemsChangedEventHandler handler = null;
    handler = (o, a) =>
    {
        // Find the root bookmark:
        XmlDocument settingsDocument = SettingsRepository.Instance.SettingsDocument;
        XmlNode bookmarkFolderNode = 
                      settingsDocument.SelectSingleNode("Settings/BookmarkFolder");

        TreeViewItem treeViewItem = 
                      generator.ContainerFromItem(bookmarkFolderNode) as TreeViewItem;

        if(treeViewItem != null)
        {
            treeViewItem.IsSelected = true;
            generator.ItemsChanged -= handler;
        }

    };

    generator.ItemsChanged += handler;

}

Basically, what I have is an XmlDocument that I use to hold global settings. Included in these settings are "Bookmarks", which are just references to files that the application opens. To display bookmarks, I have a DataTemplate that I use throughout the program that is bound to the root bookmark element of this document. Everything works flawlessly, until I want t o programmatically select a particular element in the tree view based on the XmlElement that I want to have highlighted.

The code above will actually do this properly. The handler delegate is invoked whenever the ItemContainerGenerator updates it's contents, which occurs asynchronously with the loading of the window in which this tree view is embedded. Oddly, however, if I take the same code you see above and move it into the constructor of the window, It won't work! Why it won't work is anybody's guess, but it appears to me as if the object returned by the ItemContainerGenerator property changes in between the time that the window is created and the TreeView.Loaded event is fired. This change causes the handler delegate not to return anything useful; but that's the only explanation that I have. All I know is that if you put the code above in the Loaded handler of a TreeView, it will work. Otherwise, it will fail - and the call to ContainerFromItem will always return null. Very strange...