Think different about mock objects!

Recently, after the post on mock objects by Uncle Bob (“Manual Mocking: Resisting the Invasion of Dots and Parentheses”), a rather long discussion thread grown in the extreme programming italian newsgroup (starting here, but careful, it’s in italian, sorry!).
This led me to think more deeply about my experience with mock objects, and I’d like to share my point of view here, as it’s quite different (or so it seems to me) from the common opinions on this important topic.

I’ve always followed the so-called (as Giuliano would say, isn’t it Giuliano? :-) “English School” of mock objects, the one coming from the pioneering works of Tim Mackinnon, Steve Freeman and Nat Pryce, the real fathers of mock objects.

And I’ve always carefully followed their advice, first through their *epic* paper  “Mock Roles, not Objects” (http://www.jmock.org/oopsla2004.pdf) – IMHO the best paper on mock objects and on object oriented programming with mocks – then through their terrific posts on the blog www.mockobjects.com, and finally, through their first (and brand new) book, “Growing Object-Oriented Software, Guided by Tests”.

One thing I learn is that mock objects are a design tool, while many people see it only as a technique for speeding up unit tests.
And in this context mock objects are a key tool to support your TDD process, especially in test-driving your domain model, where you follow a process similar to traditional top-down development, in which you start from the highest level of abstraction and then proceed, layer by layer, to reach the core of the domain and then move again towards the boundary of the system, towards the “services” (you can find many similarities in Cockburn’s approach to Hexagonal Architecture).

Then, when you reach the domain boundary, you should stop using mocks.
Mock objects are useful to TDDing the thin adapter layers to your services (that is, third-party libraries or external components (e.g. a database, a JMS queue, …). But then, the actual adapters will be tested with integration testing.

Why?

Because you should use mock objects as far as you can apply TDD, whereas you can design and *discover* interfaces (and roles), and assign responsibility. On the other hand, in front of a third-party library you cannot follow this process, since the code is not under your control, and you cannot modify it.

Because if you use mock objects with third-party libraries (two concrete examples taken from our recent projects: isolating our tests from the database in a Rails app, or in a java app using Hibernate ORM), you’ll write tests that *guess* the library behaviour, and your guesses may be far away from the actual behaviour.
Raise your hands if you never burnt your fingers with this kind of test with mocks, where maybe you *thought* you had a save() method to return an A object while in fact it returned B object! :)

And finally, because this kind of tests with mocks end up to be long, unreadable and fragile (an “invasion of dots and parentheses” reported by Uncle Bob in his post), full of mocks and mock expectations. And, hey, you cannot refactor them, since you don’t own the third-party code!



To verify the correct integration with libraries or external components, which are out of you domain, as well as with integration tests, you may use fakes or stubs (and, by the way, the example in the Uncle Bob’s post is actually a stub, not a “hand-rolled mock”).

So, I’ll repeat myself, following this “mocks as a design tool” approach, you’ll mock only types you own.

Some useful references to study this topic in depth (you’ll be OK even if you read just the first 2-3 links :-)

I hope I give you some useful feedback on this topic!

And, by the way, feedbacks are warmly welcome!

Leave a 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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s