Archive for August, 2008

AJAX Travelogue (Part 7): MockMe

August 9, 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.

AJAX Travelogue (Part 6): Mocking in JavaScript

August 8, 2008

It’s been a while since I have written about AJAX development; I published Part  5 over two years ago. Why’s that, you ask? Well, at a given time I was either too busy actually doing AJAX stuff or – at other times – my focus had shifted away. It wasn’t before my talk about Test-Driven Ajax had been accepted for Agile 2008 that I finally took my time and rethought some of the things I had learned about the topic before.

Let’s set up the stage for part 6 of this show, which will deal with mocking in JavaScript. As a prerequisite I assume that you are using some kind of unit testing framework for JavaScript, like JsUnit or JsUnit (well, there exist two having this name) or – like I do – the framework coming with script.aculo.us.

Effective unit testing & especially test-driven development require that you test your units (think “functions” or “objects”) in isolation. That’s how stubbing & mocking come into the picture. Whereas mocking frameworks play a significant role in statically typed languages like Java or C#, some claim that dynamic languages don’t really need that kind of thing because the mere presence of closures and duck typing make mocking and stubbing by hand so easy. JavaScript has both – closures (aka functions) and duck typing, so let’s see how things turn out in a simple example. Consider the following two objects:

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

I would like to write a test for DoubleSpeaker.say to verify that Speaker.say is being called with the argument duobled. Since using the real Speaker object would result in an alert box, which is not suitable for an automated test, I have to find a way to substitute Speaker.say with some kind of mock function:

  testDoubleSpeaker: function() { with(this) {
    var actualMsg = null;
    var mockSay = function(msg) {
      actualMsg = msg;
    };
    Speaker.say = mockSay;
    DoubleSpeaker.say('oops');
    assertEqual('oopsoops', actualMsg);
  }}

This approach actually works, but it has a drawback. Since Speaker is a global object our test has changed the global state and other tests – those that want to use the real Speaker.say function – might fail because of our test. This sort of test interdependency is one of the biggest smells of unit testing, so we have to get rid of that stink and reset the global state on finishing:

  testDoubleSpeaker: function() { with(this) {
    var actualMsg = null;
    var mockSay = function(msg) {
      actualMsg = msg;
    };
    vor originalSay = Speaker.say;
    Speaker.say = mockSay;
    try {
      DoubleSpeaker.say('oops');
      assertEqual('oopsoops', actualMsg);
    } finally {
      Speaker.say = originalSay;
    }
  }}

To me that code looks an awfully lot like my very early mocking attempts with Java around 2001. The code is bloated and full of ceremony. The essence of the test could be written down in three lines:

  testDoubleSpeaker: function() { with(this) {
    makeAMockOf(Speaker.say);
    DoubleSpeaker.say('oops');
    checkThat(Speaker.say).wasInvokedWith('oopsoops');
  }}

I’ve intentionally chosen rather wordy lines to make it clear that this is not a real API – not that I’m aware of.

My personal take-away from even a simple example like the one above is two-fold:

  • Even a language like JavaScript can make good use of a framework to take the tedium away from mocking and stubbing.
  • Such a framework must be different than mock frameworks in other languages to compensate for the difference in programming idioms (e.g. the paramount use of global objects) and the fact that the basic building block in JavaScript is NOT the object but the function.

Luckily, you don’t have to write such a beast yourself, it is already out there… (to be continued)

Sleepless in Toronto

August 7, 2008

So, I’m here in Toronto at the Agile Conference. It is 4:31am now, which tells you that my body is still somewhat drawn between night and day. Never mind, though, that gives me time to write. Since this is my first visit to a conference in North America, I actually met – or at least saw – many of the people for the first time that I’ve known by email, by blog or by gossip for quite a few years. One fact that is being noticed “by the community” is the very low number of German participants and speakers. I’ve counted only five presentations from compatriots, that’s not much more that one percent. Any idea anyone why’s that so?

Let me give you my personal ramble through the conference:

On Monday my body partally participated in the Agile Alliance’s full day workshop on Functional Testing Tools. Although this name might not sound like the most sexy thing in the world, the group comprised many of the innovative minds of the field. It’s a pity that I was so jet-lag-struck that I had to go for a short 2-hour-nap during lunch; therefore my active participation was almost non-existant. Here are some of the results.

Tuesday was my personal presentation day. Given a competition of 44 concurrent talks, I was very content with having 30+ (male only) listeners. The most fundamental questions coming from the audience was: (a) Would you say that TDD for Ajax works as smooth as in a Java only environment. (b) Would you really go for all the hassle to make your FIT-driven Selenium tests independent from “The Web” by simulating “The Web”? Given my current knowledge the short answers are: (a) It’s not as smooth but you it can be fun all the same. (b) I would strive very hard to avoid it.

Wednesday was my drifting day. I went in and out of sessions as I pleased – and I pleased the lot. However, Neal Ford’s talk on Ancient Philosophers & Blowhard Jamborees was so entertaining that I stayed to the end despite myself. Among many other citations and anecdotes he brought up a quote from Glenn Vanderburg:

Bad developers will move heaven & earth to do the wrong thing.

It’s a sad truth, because it eventually means that we cannot shield our software from incapable developers by technical means like stricter type systems, higher abstractions & tighter code ownership. At the end of the day we have to get rid of the NNPPs provide the NNPPs with alternative career paths. Will they be less or more happy that way? How certain can I be that I haven’t joined that crowd yet?


Follow

Get every new post delivered to your Inbox.