The Past, Present and Future (?) of Mocking

(Note: I’m going to speak about .NET mock projects here for the most part, but most of them have Java quasi-equivalents.)

The original mocking frameworks like NMock required you to setup expectations by passing strings for method names. This was fragile and made refactoring more difficult.

A few mock frameworks now allow you to define expectations and mock results in a strongly typed manner. Rhino Mocks and TypeMock use a record/replay method to setup expectations. The record replay method is mostly necessary because the same calls are made on the same objects under two different scenarios. This leads to a few issues.

The first issue is confusion and barrier to entry. Many people have complained that the Record/Replay method is not straight forward and the whole paradigm is confusing. There are also complains about the naming, are you really recording and then replaying? It’s just kind of a strange thing. Of course most of us learn to live with it, understand it, and accept it for what it is. Recently though, a few mock frameworks have popped up that do away with this model.

In the .NET world we have Moq. Moq gets rid of the need for record/replay because recordings have a very different syntax. They use lambdas instead of actual calls to the mock object. This allows the framework to know when you are recording an expectation and when you are fulfilling an expectation. It adds a bit of noise in the form of "() =>" but all in all it’s not bad. Of course this requires C# 3.0, but it’s good to keep looking ahead.

In the Java world we have Mockito. Mockito also does away with the record/replay model but it does it in a different way. At first I wasn’t a fan, but thinking about it more, I like it. Mockito has two main apis, stub and verify. Stub is equivalent to SetupResult.For, and verify is equivalent to Expect.Call with a verify. The interesting bit is that the stubbing happens before the the class under test is invoked and the verifying (which includes describing the method to be verified) happens after the class under test is invoked. This is best shown with an example stolen from the Mockito site:

  
  //stubbing using built-in anyInt() argument matcher
  stub(mockedList.get(anyInt())).toReturn("element");
  
  //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
  stub(mockedList.contains(argThat(isValid()))).toReturn("element");
  
  //following prints "element"
  System.out.println(mockedList.get(999));
  
  //you can also verify using argument matcher
  verify(mockedList).get(anyInt());

Obviously it would take a bit of imagination to arrive at a .NET equivalent, but you get the idea. I like this because the normal test structure is Setup Stuff->Do Stuff to Test->Verify Stuff did what it should have. The normal record/replay model requires you to set up verifications before you actually Do Stuff (though you call VerifyAll afterwards). This is a bit less natural. I feel syntax like this (yeah, I like the new NUnit syntax) would be more intention revealing:

Assert.That(() => someMock.Foo(), Was.Called);

Or:

Verify.That(() => someMock.Foo()).WasCalled();

Then you would stub like this:

Stub.That(() => someMock.Bar()).Returns(3);

(Note: No idea if this is feasible or makes sense or not, my lambda experience is limited to light reading, but you get the idea. I’m sure the syntax could also be prettier.)

Rhino.Mocks is my current mock framework of choice. I’m used to it, I’ve lightly contributed to it, and I’ve been working with it for a while now. Despite that, I do think that there is definitely more to explore in the mocking arena especially with C# 3.0.

There are lots of other fun things to talk about too… like TypeMock‘s magic, but that’s another day still…

This entry was posted in frameworks, mocking. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.rgoarchitects.com/nblog Arnon Rotem-Gal-Oz

    In Java you can also use Ruby’s Mocha framework (on JRuby) see for example
    http://memeagora.blogspot.com/2007/10/mocking-jruby.html

    Arnon

  • Aaron Jensen

    Johnson,

    I haven’t looked at it to be honest. I’ll check it out.

  • Johnson

    What about jMock in the Java world. That doesn’t use strings to identify methods but still has a “DSL” style API and can specify interactions between stateful objects, which Mockito cannot.