Are Too Many Mocks A Code Smell?
Recently I have been involved in an excellent discussion the testdrivendevelopment yahoo mailing list regarding a concearn I had over whether using expectations with mock objects cause you to violate encapsulation, and received very many good replies, and during the thread one of the authors of RMock stated that :
I think when using mocks, absurd abmounts of setup code is an indication that your design could be improved. I have no concrete
metrics for you but I would stat looking if I can simplify my design if I require more than 10 or so lines of setup. Sometimes it is hard. Usually you are doing too much at the time and then srp can be your guide.
To which I found to be quite true. At that time the conversation had drifted to whether or not mocks can sometimes slow you down with too much setup code, as my partner and I were dealing with a test we were writing that had an insane amount of mocks and setup. However, that same day we discovered that, yes, our object we had under the test had too many responsibilities and few collaborators. Once we broke these responsibilities out into seperate objects and refactored our unit test to move responsibilities to the tests for those objects, we discovered something. The setup reduced dramatically, and at the same time some of our newer objects no longer even needed mocks as they were no longer forced to “touch” the responsibilities that used those objects.
Anyway, where I’m getting at with this is that Joakim Ohlrogge (one of the authors of RMock) posted a new thread to discuss this topic in greater detail, and linked to an article that explored the difference between state and interaction based testing.
The idea is that state based is that you just want to test the state of an object at certain conditions… you give it input and then validate it is in the state you expect it to be or that the state exists that you expect. For example, at work we may do this in a unit test for a rule by generating a record that will be supressed based on the criteria the rule represents, pass the record through the rule, then validate that the record object’s state is supressed.
However, in interaction based testing, things are much more fine tuned and you care about how your object interacts with it’s environment… what external resources it accesses, what collaborators it works with, what messages it passes around, etcetra. Essentially, you test it’s interaction. I have to agree with the strengths of interaction based testing as opposed to state based in that state based testing can be much more difficult, as Nat Pryce elaborates,
Mutable state makes a program harder to understand and maintain because the behaviour of a piece of code cannnot be easily predicted merely by reading the text but depends on the sequence of events that put it and its environment into signigicant states. By concentrating on the interactions between objects instead of state changes, interaction-based testing guides the design towards objects that transform data as they pass it around rather than store data and perform logic on the state of other objects.
Martin Fowler also provides some excellent examples of state-based vs. interaction based testing on his site
in the article Mocks Aren’t Stubs, which is also an excellent article for those who might be new to mock objects.
To stay back in touch with the post topic … are too many mocks a code smell? In my opinion, yes. If you have too many mocks and too much mock setup, perhaps this is a sign that your object either has too many collaborators, too many dependencies, or too much coupling with external resources. Once you break the responsibilities up, however, I often find the tests for those new objects are much smaller and much cleaner.
If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!








August 15th, 2006 at 9:05 am
I agree. Having many mocks for your test code doesn’t mean it is easier to test it in isolation, it means you are doing too much with that class, and that it could be refactored in smaller parts.