Mathias Brandewinder on .NET, VSTO and Excel development, and quantitative analysis.
by Mathias 4. June 2010 12:19

I am very honored that the East Bay chapter of the Bay Area .Net user group will have me as a speaker this upcoming Wednesday. I’ll be talking “For Those About to Mock”, about Mocks and Stubs in .Net, after a presentation of the unit testing features of Visual Studio by Deborah Kurata – an apt opening topic, if you ask me.

You can find more information about this event here; Hope to see you on Wednesday!

by Mathias 23. April 2010 09:24

pexweb I gave a lightning talk on Pex at the San Francisco .Net user group this Wednesday, and figured I might as well post the slide deck. Pex is a fascinating free add-in to Visual Studio, totally worth looking into: unleash Pex on a method, and it will identify interesting input values for you.

Download the slide deck here.

by Mathias 5. April 2010 11:59

A few weeks back, Michael asked an interesting question in a comment: how do you go about unit testing a VSTO project? One of the reasons I prefer working with VSTO over VBA, is that it makes it possible to write automated tests. What I realized with this question, though, is that I unit test heavily the .Net functionality of my add-ins, but not much (if at all) the interaction with Excel.

Note: I am aware of the existence of a VBA unit testing solution, xlUnit; I found the project conceptually pretty cool, but from a practical standpoint, it doesn’t seem nearly as convenient as NUnit or the other established frameworks, which isn’t much of a surprise, given the maturity of unit testing in the .Net world.

The reason for this is double. First, most of my VSTO projects focus on generating heavy computation outside of Excel, and writing results to Excel; as a result, the meat of the logic has little to do with Excel, and there isn’t all that much to test there.

Then, testing against VSTO is a bit of a pain. By definition, a VSTO project comes attached with a giant external dependency to Excel, which we have limited control over, and which is also rather unpleasant to deal with from .Net. To illustrate one aspect of the issue, let’s consider this code snippet:

[TestFixture]
public class TestsThisAddIn
{
   [Test]
   public void WeCannotInstantiateTheAddInProperly()
   {
      var addIn = new ThisAddIn();
      var excel = addIn.Application;
      Assert.IsNotNull(excel);
   }
}

This test will fail: if we instantiate the add-in directly, it does not automatically hook up to Excel. The VSTO add-in is started up by Excel itself, and we cannot replicate that simply in our test code, and access the Excel object to verify that things behave as expected.

So how could we approach the problem? Unit testing our code means that we want to validate that pieces under our control (classes we wrote) work properly; the challenge is that some of them interact with Excel. We are not concerned with testing the system in its entirety (add-in code + Excel) here, which is an important issue, but not a unit-testing one.

The words “unit test” and “external dependency” together suggest one technique – Mocking. In a nutshell, Mocking consists of replacing the external dependency with a fake, an object which behaves the same way as the “real thing”, but is easier to work with.

There are three ways our classes can interact with Excel that I can think of:

  • react to Excel events
  • read/query from Excel
  • write/command to Excel

More...

by Mathias 27. January 2010 18:26

Mark Needham recently published a series of posts around TDD, and one caught my attention. He is mocking a series of calls to a method SomeMethod() of a service IService, and doesn’t really care about the arguments, but:

For the sake of the test I only wanted 'service' to return a value of 'aValue' the first time it was called and then 'anotherValue' for any other calls after that.

His solution is to ditch his mocking framework (Rhino.Mocks, as far as I can tell) for that one test, and hand-roll his stub – and his example is a good case for why you might want to do that, sometimes.

However, this got me curious, and I wondered if this was indeed possible using Rhino. As recently as last week, I struggled with mocking repeat calls; but I had never actually considered a situation where one might want to mock a method, focusing only on the fact that the method is called, without paying attention to the specific arguments passed. Fun stuff.

After some digging into the documentation, I came across IgnoreArguments(), which seems to do the job:

public void SpecifyFirstReturnThenReturnSameThingForeverAfter()
{
    var fakeService = MockRepository.GenerateStub<IService>();
    fakeService.Expect(f => f.SomeMethod(null)).IgnoreArguments().Return("First").Repeat.Once();
    fakeService.Expect(f => f.SomeMethod(null)).IgnoreArguments().Return("SecondAndAfter");
    
    var first = fakeService.SomeMethod("ABC");
    var second = fakeService.SomeMethod("DEF");
    var third = fakeService.SomeMethod( "GHI" );

    Assert.AreEqual("First", first);
    Assert.AreEqual("SecondAndAfter", second);
    Assert.AreEqual("SecondAndAfter", third);
}

IgnoreArguments() seems to be a potentially convenient way to make some tests lighter. That being said, arguably, the setup here is cumbersome, and the hand-rolled version is clearer: when you reach the point where you wonder if your mock is doing what you think it should, you enter perilous territory…

Comments

Comment RSS