InfoQ

News

"Classic" versus "Mockist" TDD, Distinction Real?

Posted by Mike Bria on Jan 22, 2009

Community
Agile
Topics
Software Craftsmanship ,
Software Testing ,
Unit Testing
Tags
jMock ,
Mocks ,
Design by Contract ,
TDD

Hot in the Test-Driven Development Yahoo group this week is a discussion concerning the perceived continuum between the so-called "Classic" and "Mockist" approaches to TDD. Steve Freeman, Nat Pryce, Michael Feathers, Dale Emery, and many more discuss terminology and describe their approaches. The discussion also debates whether there even really exists such a continuum, and if so, what distinguishes the approaches that represent it's extremes?

After stating he "feels inclined to the classic-TDD approach", Olaf Bjarnason started the 70+ entry discussion with this question to the group: "What made you switch [to "mockist"] from classic, if you were there before? How does the new method feel?". Many of the early responses though centered more around a challenge Olaf's thread title, "Classic/Mockist discussion". Is there really a need for such a binary distinction?

Nat Pryce, co-creator of JMock, expresses his feeling:

I think the whole division of TDD practice into "mockist" vs "state based" is pointless, distracting and does a disservice to people trying to learn and use TDD.

Mock objects are just a tool. They are one of many tools that you need to use when doing TDD. Like any tool, they are designed to help solve a set of problems in a specific context. Outside that context they do not help and can be a hindrance.

If this is the case, how then does one know when to apply this "tool"? How does one know to test "state", namely without a mock, versus asserting behavior, namely by using mocks?

Dale Emery chimes in to describe how he typically makes the distinction:

Lots of people use the distinction of "state-based" versus "behavior-based." I use a twist on this. I think "result" versus "protocol". If the essence of the test is whether the UUT produced the correct result, I don't usually need a mock for that. If the essence of the test is whether the UUT properly executed its role in a protocol--i.e. whether it sent the right messages to the right collaborators, given the starting conditions and the stimulus--I use mocks to represent the UUT's direct collaborators.

Lior Friedman asserts that a mock's place is in representing a contract:

For me usage of mocks indicate the existence of a "contract" between the class under test and another class which is used. And the goal of the test is to verify that the contract is fulfilled.

Charlie Poole pitches in with his gauge on when state-based is the way to go:

I'd use state-based testing on an object if I had no other way to observe it's behavior - that is if /all/ the call did was change an observable state of the object. Assuming the object actually did something, I'd want to verify [with a mock] that it did it.

Adam Sroka on when he uses a mock:

For my own part, I *always* mock at system defined boundaries (e.g. filesystem, network, database, etc.) I usually mock when I want to elicit loose coupling between an interface and it's client in a top-down direction. And, I generally don't mock when the object I am interacting with is small and easily faked/stubbed.

As the thread goes on, and as may be highlighted by the above sound-bites from it, there is a recurring observation that while many of these ideas are similarly themed, they don't seem to share a commonly categorizable, named approach beyond "We do it sometimes, but not others". Further, each (with the exception possibly of Sroka's statement about "top-down") tend more to the following: The decision to mock is being driven by the design, as opposed to the converse, where the design is driven by the mocks.

Regarding this idea of using mocks to drive design, Michael Feathers gives an example:

To me, the real meat behind the whole subject is just how far people are willing to push "tell, don't ask." Mocks are a prop for a design approach.
...
Imagine you have some object and you want to get report of its errors:

    class Errors {
        int errorCount();
        Error getError(int index);
    }

    Errors errors = object.getErrors();


That's an ask. We can do state-based testing of the Errors object in the test.
To make it a tell you'd move to this:

    interface ErrorReceiver {
        void accept(Error error);
    }

    ErrorReceiver receiver = ...;
    object.reportErrors(receiver);

We can set expectations on a mock receiver and pass it during testing and use a "real" class in production.

Later, largely in response to a post by Steve Freeman (another co-creator of JMock) describing his partner Nat Pryce's categorization of some "mock-worthy peer objects" ("Dependencies","Notifications", and "Policies"), Feathers (and also Colin Jack) assert that the design ideas the duo have been putting forth in fact exist at the core of this "mocks as a tool to drive design" philosophy. Further, more to the point of this thread, that when people talk of a "mockist TDD approach" they are referring in large part to these design ideas, and that the recurring confusion about "Classic vs Mockist TDD" could be reduced if these collection of ideas had a more concrete name.

As Pryce reminds the group, he and Freeman have a book in the works that may just provide some this clarification being requested. He also points the group to a write-up of his on "State vs Interaction Based Testing".

So, keeping it real, this conversation is really not a new one (Google it), but it is it seems a recurring one. Is there a "Classic TDD", and does it mean "Design begets Mocks"? Is it characterized by something else? Is there "Mockist TDD"? Is it characterized by a "Mocks beget Design" philosophy? "Tell, Don't Ask"? Is it something altogether else? Either way, is it really a "this OR that" thing, or more likely "this for these AND that for those"?

Of course, as always, this news is simply a [hopefully objective] highlight of the Yahoo group discussion, and as such only a piece of the puzzle. Read it for yourself, as well as other sources, and tell others here and/or in the discussion what your experience says.

Related Sponsor

VersionOne is recognized by Agile practitioners as the leader in Agile project management tools. Companies such as Adobe, BBC, CNN, Dow, HP, IBM, Sony and 3M have turned to VersionOne to help deliver greater value to their customers.

bad link by Clay Smith Posted Jan 24, 2009 7:54 AM
Re: bad link by Mike Bria Posted Jan 24, 2009 12:59 PM
Re: bad link by Rhys Campbell Posted Jan 25, 2009 9:08 AM
Re: bad link by Mike Bria Posted Jan 25, 2009 1:59 PM
Perhaps by Michael Hedgpeth Posted Jan 24, 2009 8:02 AM
Test what you want to expect by Rhys Campbell Posted Jan 25, 2009 9:11 AM
  1. Back to top

    bad link

    Jan 24, 2009 7:54 AM by Clay Smith

    Could you provide the real link to the discussion group? I don't find some-site.com to be particularly useful.

  2. Back to top

    Perhaps

    Jan 24, 2009 8:02 AM by Michael Hedgpeth

    Perhaps it's more of an argument among those who haven't done TDD for a while. Talking about the distinction and leading people towards state-based testing will keep then from being too extreme and entering an unfortunate place I call "mock hell".

    With the knowledge of mocks in hand and the understanding that they are to be used sparingly, new TDDers will find themselves in the balanced place that the gurus on the list (above) are at.

  3. Back to top

    Re: bad link

    Jan 24, 2009 12:59 PM by Mike Bria

    Hm, sorry Clay, not sure what you mean. All seems fine to me?

    Cheers
    MB

  4. Back to top

    Re: bad link

    Jan 25, 2009 9:08 AM by Rhys Campbell

    final link in the post "Yahoo group discussion" goes no where:
    [quote]
    Of course, as always, this news is simply a [hopefully objective] highlight of the Yahoo group discussion, and as such only a piece of the puzzle. Read it for yourself, as well as other sources, and tell others here and/or in the discussion what your experience says.
    [/quote]

  5. Back to top

    Test what you want to expect

    Jan 25, 2009 9:11 AM by Rhys Campbell

    I personally think its somewhat of an inane argument. If the test is requiring interaction, use a mock. if it requires a change of state use an assert. How this picked up traction.. I really don't know..surely there is some code to written team... get to it!

  6. Back to top

    Re: bad link

    Jan 25, 2009 1:59 PM by Mike Bria

    Got it, thanks!

Educational Content

Brian Marick on 4 Challenges and 5 Guiding Values of Agile Software Development

Brian Marick takes us through a quick tour of the most important values and challenges to adopting Agile successfully (they aren't the typical challenges and values we hear in the community).

Are You a Software Architect?

The line between development and architecture is tricky. Does it exist at all? Is an ivory tower actually needed? There's a balance in the middle, but how do you move from developer to architect?

Agile – A Way of Life and Pragmatic Use of Authority

The word 'authority' sometimes produces an allergic response in hard-line agilists. Freedom and authority – both are bad if misused and both are good if used in right spirit for a noble cause.

Getting Started with Grails, Second Edition

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, and Taco Bell are all using Grails. Are you ready to get started as well?

Using ITIL V3 as a Foundation for SOA Governance

Those familiar with only ITIL V2 often scoff at the thought that ITIL could serve as a governance framework for SOA. With ITIL V3, the focus of the framework shifted towards service-orientation.

Adrian Colyer on AspectJ, tc Server and dm Server

SpringSource CTO Adrian Colyer discusses AspectJ, SpringSource's dm Server and tc Server products, OSGi and Scrum.

Adam Wiggins on Heroku

Heroku's Adam Wiggins talks about Rails, Background Jobs, Add-Ons, Ruby, and how Heroku manages to work around Ruby's inefficiencies using Erlang and other languages.

SOA as an Architectural Pattern: Best Practices in Software Architecture

For Grady Booch the foundation of a good architecture is patterns, SOA being just one of many patterns. In this Second Life presentation, Booch attempts to bring more clarity on what architecture is.