Mock Frameworks, not for everyone and everytime

A frequent question is when should I use a mock object framework ?
However, if you have to ask “when”, the answer is probably “not now”. I feel that mock object frameworks are something you have to evolve into.

First, we can talk about mocks in general. Some people have a misconception that mock objects are only useful if you need to simulate interaction with a resource that is difficult to use in unit tests – like an object that communicates with an SMTP server. This isn’t true.

* The real object has nondeterministic behavior
* The real object is difficult to setup
* The real object has behavior that is hard to trigger
* The real object is slow
* The real object is a user interface
* The real object uses a call back
* The real object does not yet exist

If we were to step back and generalize this list, we’d say test doubles are useful when you want to isolate code under test. Isolation is good. Let’s say we are writing tests for a business component. We wouldn’t want the tests to fail when someone checked in bad code for an auditing service the business component uses. We only want the test to fail when something is wrong with the business component itself. Providing a mock auditing service allows us to isolate the business component and control any stimuli the component may pick up from its auditing service. When you start feeling the pain of writing numerous test doubles by hand, you’ll know you need a mock object framework.

Mocks aren’t just about isolation, however. Mocks can play an important role at any time if employed correctly. Mocks can be powerful technique for identifying types in a system based on the roles that objects play … In particular, we now understand that the most important benefit of Mock Objects is what we originally called interface discovery.

Using a mock object framework allows a continuous, top-down design of software. But Aren’t Mock Object Frameworks Complex?

This is another question I’ve been asked recently. Mock object frameworks are actually rather simple and expose a small API. There is complexity, though, just not in the framework itself. As I said earlier, I think there is a path you can follow where you evolve into using mock object frameworks. The typical project team using a mock object framework is experienced with inversion of control containers. Trying to get up to speed on all these topics at once can be overwhelming.

There is also some complexity in using mocks effectively. In Mocks and the Dangers of Overspecified Software, Ian Cooper says:

“When you change the implementation of a method late in the implementation process, mocks can break because you now make additional or different calls to the dependent component that is being mocked. … The mocks began to make our software more resistant to change, more sluggish, and this increased the cost to refactoring. As change becomes more expensive, we risked becoming resistant to making it, and we risk starting to build technical debt. A couple of times the tests broke, as developers changed the domain, or changed how we were doing persistence, without changing the test first, because they were frustrated at how it slowed their development. The mocks became an impedance to progress.”

Mock object frameworks make interaction based testing easy, but can also lead to the problems Ian outlines. Here a couple more reads on this topic:

* Guidelines to Using Interaction Based Testing
* Why Mock Frameworks Suck

In summary – mock object frameworks aren’t for everyone. You’ll know when you need one!

2 thoughts on “Mock Frameworks, not for everyone and everytime

  1. I realize that some of the pointed out problems are reasonable. Some of the issues may be solved by using right mock framework. You could give a try to this one: http://bitbucket.org/loomis/mockito-flex/. It is not record/replay. Instead it lets you verify only what you are interested in and stub only what you need to. Someone pointed out that this approach don’t let you see problems in the code (as you may give up on specifying some of the interactions). I believe you can easily address it by adding enough tests that focus on the behavior of the function.

    1. Hi Kris,

      Thanks for your input, now the post is more than a year old, so I realize that a lot of things have changed. Perhaps its time for me to revisit the topic and write more about it…

      // Peter

Leave a Reply to Peter Andreas Molgaard Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s