Published: August 09 2008

In the previous episode you've learned why a mocking framework seems to be a reasonable idea even in a language that provides closures and duck typing. MockMe is such a framework. I started to develop it after fighting the usability war with the existing ones I found out there.

MockMe has two fundamental ideas:

  • The basic granularity of mocking should be the function. If I want to, I can fake the behaviour of a single function without influencing the rest (of an object or a prototype or the global namespace or whatever).
  • Most of the time, spying is a better idea than mocking because it's simpler. Spying basically means that, instead of specifying the expected interaction with your mock spy object before doing the test, you use the mock spy object to spy into the interaction as it happens and verify that afterwards. In that respect I borrowed heavily from mockito, a spying framework that's gaining more and more attention in the Java world.

Let's look at the example from yesterday:

  var Speaker = {
    say: function(msg) {
      alert(msg);
    }
  };
  var DoubleSpeaker = {
    say: function(msg) {
      Speaker.say(msg+msg);
    }
  };

We would like to write a test for DoubleSpeaker.say to verify that Speaker.say is being called with the argument duobled. Using MockMe the test looks like this:

  testDoubleSpeaker: function() { with(this) {
    mock(Speaker).andDo(function() {
        DoubleSpeaker.say('oops');
        verify(Speaker.say)('oopsoops');
    });
  }},

That's fairly easy, isn't it. It has only a third of the lines compared to the hand-crafted version.

There are mainly two reasons I prefer spying over mocking: (a) It does not break the standard testing flow of setup -> test -> assert. (b) It's harder to overspecify your implementation's behaviour.

The difference between spying and mocking has been described by Gerard Meszaros in his book on test patterns. Among many other valuable contributions he succeeds in sorting out the differences in the terms used by different writers. That said, I still call MockMe a mocking framework for the selfish reason that mock has become the term that is being used most in the agile testing community.

To wrap up, the next example demonstrates that stubbing with MockMe is equally straightforward:

  testStubbing: function() { with(this) {
    useMockerFor(function(mocker) {
      var f = mocker.mock();
      when(f)(1, 'two').thenReturn('hiho');
      assertEqual('hiho', f(1, 'two'));
    });
  }}

Here is where you can find more on how to use MockMe.

blog comments powered by Disqus