Stephen Freeman Rotating Header Image

The big idea is "messaging"

I’ve been fretting over why so many smart people don’t quite get what we’ve been trying to express with Mock Objects, and why we as a group think it matters. There’s an experience we haven’t been getting across properly. I think the step that’s missing is the extent to which we use the “Tell, Don’t Ask”:http://www.pragmaticprogrammer.com/ppllc/papers/1998_05.html pattern.

We pass behaviour in, rather than extracting state from an object. Really we do. In fact, the whole thing started at a session of the London Architects’ Group when John Nolan asked what would happen if there were no getters. Combine that with Remove Duplication and Express Intent, and you have a very clean and flexible code base. Unfortunately, with everyone else using Java Beans and .Net properties, you also have a very unusual code base which might explain our difficulties.

The style we’ve developed concentrates on what objects say to each other, rather than how their state changes. Many people think that this locks down the test code because you’re tracking its implementation, but that’s less true if you can specify the conversation at the right level. If you tell the Agent to Purchase a Quantity at a Price, that’s both more meaningful than telling it to Commit an Integer with a Decimal, and more flexible when it turns out that the price includes a currency.

The key for me was when “Joe Walnes”:http://joe.truemesh.com/blog/ came up with the radical notion of “Don’t mock types you don’t own”. This means: stop jumping through hoops to work with closed-world libraries, use the tests to discover your objects and _what they say to each other_. Don’t just take my word that this is a good way to think about code, see Alan Kay’s “posting to the Squeak list”:http://lists.squeakfoundation.org/pipermail/squeak-dev/1998-October/017019.html

bq. The big idea is “messaging” — that is what the kernal of Smalltalk/Squeak is all about (and it’s something that was never quite completed in our Xerox PARC phase). The Japanese have a small word — ma — for “that which is in between” — perhaps the nearest English equivalent is “interstitial”. The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.

As a community, we were diverted by an attempt to mock out the whole of the java libraries. Now that feels both overambitious and pointless. Apart from the scale, many of the stadard libraries do not mock well because their interactions are too complex, JDBC for example. Now we’ve got over that, and with “jmock”:www.jmock.org almost ready which will avoid the need to pre-build mocks, perhaps we can get back to the important stuff.

7 Comments

  1. Alan says:

    That post just made me a whole lot less sceptical of “the mock scene”.

    During all that MockJDBC and MockVisualAge phase I was just really confused. A MockJDBC surely just encoyurages me to pepper my app code with JDBC calls cause I know I can mock it out at test time. What I’d rather do is have Database and MockDatabase with a custom API. Database can be implemented on top of JDBC and MockDatabase can do whatever. “Don’t Mock what you don’t own” is, IMO, a rule that badly needs publicised.

    Just my 2c.

    A.

  2. arton says:

    Thanks, I think that I see what you said ‘design’.
    I suppose that your main focus using mocks is to find the appropriate objects in the domain and the right interfaces to interact each objects – so, not limited in implementation (unit testing) but the design or to build the implementation model. Am I right or missing some points ?

  3. Chad Woolley says:

    Great post. However, I think the “Don’t mock types you don’t own” concept could be clarified more. I think that many people will still say: “…but how can I avoid hitting my database if I don’t mock JDBC?”.

    I believe the key to this is to wrap a thin (the thinnest possible) layer around any external class that you would otherwise feel the need to mock. Then, you can mock this, because you “own” it.

    Your team has written about this approach on the mockobjects.com site: http://www.mockobjects.com/wiki/MockableAdapter, and this technique has been discussed on the TDD group.

    So, I think this is a key concept to mention whenever you mention the “Don’t mock types you don’t own” rule.

    Thanks,
    Chad

  4. Steve Freeman says:

    Arton: I think we’re in agreement, although there are some language issues 😉

    Chad: er, yes. As a group we’re still writing, so there’s more to come. It just seemed like such a good quotation to use.

  5. Chad Woolley says:

    Another important point here is the use of interfaces. In your group’s writings, you espouse the use of interfaces in driving the mock object process: http://www.mockobjects.com/wiki/MockObjectsProcess

    However, I think things have changed since the advent of CGLib-based approaches that remove the need for an interface in order to mock an object. The latest version of jMock has this support, as does EasyMock. It is fairly easy to implement in any dynamic-proxy based mock approach.

    In many cases, I think you can follow your process, but without the interface step. Just use the actual class, and only define an interface if you need it for some other application-specific reason (not just in order to mock it).

    I’ve been thinking a lot about this topic, and I’d like to get some feedback. What do you think the appropriate forum to discuss it would be?

    Thanks,
    Chad

  6. Steve Freeman says:

    I disagree about interfaces. nMock does class and interface generation, but I still use interfaces with it. You could try posting to, say, mockobjects-users, but we’re in a writing burst at the moment and so a bit busy. If you can wait a little while we might have something more substantial for you to read. In the meantime, you might want to think about interfaces as describing roles, and people (and objects) can have more than one role.

  7. Chad Woolley says:

    Hmmm. Well, I’m not subscribed to mockobjects-users currently, and I’m swamped with real work at the moment, so I’ll make just make a brief reply here for now..

    The basic question that causes me doubts is this: What is the justification for having an interface that:

    1. is only implemented by one concrete class, AND

    2. is only ever expected to be (that is, not part of an extensible framework), AND

    3. other than the implementing class, is only cast to by dynamic mocks.

    When looking at the jMock codebase, you have very few interfaces that fall into this category (most are implemented by more than one concrete class).

    However, it is very possible to follow the “Tell don’t ask”, test-driven approach without the use of interfaces, as long as you use a mock API that supports class mocking. I still use interfaces, but only when I find or anticipate a need for it to be implemented by more than one class. If I am just creating a new class as part of TDD, I make a real class with stub methods, and mock it directly.

    I’m wondering what the fundamental differences between these approaches are. I must be missing something, but I don’t know what it is. I’ll mull over it some more and perhaps post about it on mockobjects-user in the future.

    Thanks,
    Chad