124

I’ve been hearing about the London style vs. Chicago style (sometimes called Detroit style) of Test Driven Development (TDD).

Workshop of Utah Extreme Programming User's Group:

Interaction-style TDD is also called mockist-style, or London-style after London's Extreme Tuesday club where it became popular. It is usually contrasted with Detroit-style or classic TDD which is more state-based.

Jason Gorman's workshop:

The workshop covers both the Chicago school of TDD (state-based behaviour testing and triangulation), and the London school, which focuses more on interaction testing, mocking and end-to-end TDD, with particular emphasis on Responsibility-Driven Design and the Tell, Don't Ask approach to OO recently re-popularized by Steve Freeman's and Nat Pryce's excellent Growing Object-Oriented Software Guided By Tests book.

The post Classic TDD or "London School"? by Jason Gorman was helpful, but his examples confused me, because he uses two different examples instead of one example with both approaches. What are the differences? When do you use each style?

2 Answers 2

114

Suppose you have class called "ledger" a method called "calculate" that uses a "Calculator" to do different types of calculations depending on the arguments passed to "calculate", for example "multiply(x, y)" or "subtract(x, y)".

Now, suppose you want to test what happens when you call ledger.calculate("5 * 7").

The London/Interaction school would have you assert whether Calculator.multiply(5,7) got called. The various mocking frameworks are useful for this, and it can be very useful if, for example, you don't have ownership of the "Calculator" object (suppose it is an external component or service that you cannot test directly, but you do know you have to call in a particular way).

The Chicago/State school would have you assert whether the result is 35. The jUnit/nUnit frameworks are generally geared towards doing this.

Both are valid and important tests.

6
  • Very nice example. Commented Dec 7, 2011 at 4:36
  • 3
    I'll add a few more reasons for using each: If the important thing is determining that something has or has not changed based on the action being taken (e.g., the ledger.bucket.value becoming 35 when ledger.calculate("5 * 7") is called), you want to use assertions of state (Chicago school). This is most helpful when you have full control over the state of the system before the method is called, and when you actually control what the method does. Commented Dec 7, 2011 at 20:05
  • 4
    If the important thing is knowing that a second method is called (e.g., Calculator.multiply(5, 7)), you want to use activity assertions, as through a mock object. This is most helpful if the method being called has a desired side effect (e.g., saving data, incrementing a counter, sending a message, etc.) of if you do not really control what the method does, so the return value may be inconsistent. Also, if you cannot easily control the state of the system, the best you can do may be to determine what activities occur. Commented Dec 7, 2011 at 20:05
  • 2
    The London school is also useful if you want to assert that ledger is correctly using a particular interface, regardless of whether it is implemented at runtime by Calculator or RemoteCalculator or ThreadsafeCalculator, etc. Your Mock can be initialised to raise if invalid method calls are made to the interface. A system test should assert that a system containing an instantiated ledger->calculator pairing produces the right results, but a unit test of ledger should use not be dependant on the creation or behaviour of Calculator (and all its dependencies.) Commented Mar 18, 2015 at 9:24
  • 4
    The London approach also argues to provide clearer feedback signals, because if Calculator regresses in multiply, you'll see two tests fail: the ledger test, and the calculator test, but only one test fails if you mock out the calculator. That might make it easier to pinpoint the origin of the bug, especially if the system is complex.
    – mxk
    Commented Jan 13, 2016 at 10:33
43

The article Mocks Aren't Stubs, by Martin Fowler is a good introduction to the topic.

Depending on the design style you choose (and the design principles upon which you build your programs), there are at least two ways of seeing an object:

  1. As a unit that performs computations based on inputs. As a result of this computation the object can return a value or change its state.
  2. As an active element that communicates with other elements in the system by message passing.

In the first case, you are interested in what comes out of the processing or in which state the object is left after that processing. This is where methods such as assertEquals() enter the picture. In this case, it does not matter much what other objects were involved in the processing, which methods were called, etc. This kind of verification is called state-based verification and is the "classical" style.

In the second case, since most objects do not even return any result (e.g. void methods in Java), you are more interested in how the objects communicate with each other and if they pass the right messages under the circumstances imposed by the test. These interactions are usually verified with the aid of mock frameworks. This kind of verification is called behavior-based or interaction-based verification. One of its implications is the technique called Behavior Driven Development, by which you develop a class assuming that its collaborators already exist (even though they might not exist yet), so you can code against their interfaces.

Note that this is not an either/or choice. You can have a design style that mix both approaches to get the best out of each.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.