Mark Needham

Thoughts on Software Development

TDD: Only mock types you own

with 9 comments

Liz recently posted about mock objects and the original ‘mock roles, not objects‘ paper and one thing that stood out for me is the idea that we should only mock types that we own.

I think this is quite an important guideline to follow otherwise we can end up in a world of pain.

One area which seems particularly vulnerable to this type of thing is when it comes to testing code which interacts with Hibernate.

A common pattern that I’ve noticed is to create a mock for the ‘EntityManager‘ and then verify that certain methods on it were called when we persist or load an object for example.

There are a couple of reasons why doing this isn’t a great idea:

  1. We have no idea what the correct method calls are in the first place so we’re just guessing based on looking through the Hibernate code and selecting the methods that we think make it work correctly.
  2. If the library code gets changed then our tests break even though functionally the code might still work

The suggestion in the paper when confronted with this situation is to put a wrapper around the library and then presumably test that the correct methods were called on the wrapper.

Programmers should not write mocks for fixed types, such as those defined by the runtime or external libraries. Instead they should write thin wrappers to implement the application abstractions in terms of the underlying infrastructure. Those wrappers will have been defined as part of a need-driven test.

I’ve never actually used that approach but I’ve found that with Hibernate in particular it makes much more sense to write functional tests which verify the expected behaviour of using the library.

With other libraries which perhaps don’t have side effects like Hibernate does those tests would be closer to unit tests but the goal is still to test the result that we get from using the library rather than being concerned with the way that the library achieves that result.

Be Sociable, Share!

Written by Mark Needham

December 13th, 2009 at 9:47 pm

Posted in Testing

Tagged with ,

  • Pingback: Tweets that mention TDD: Only mock types you own at Mark Needham -- Topsy.com

  • msuarz

    I’m not with this 100% … I always have two levels of tests … acceptance n’ unit … the acceptance test uses the real thing, unit mocks everything …

    If the library I’m using allows mocking I’ll mock it … If not I’ll wrap it with a interface + class or just with a virtual function + partial mock

    But in any case … the acceptance test is the one that would do the integration part … so i don’t see the big deal with this

    cheers
    mike

  • http://www.harukizaemon.com Simon Harris

    Reminds me of another post I wrote back in 2003 http://www.harukizaemon.com/2003/11/don-mock-infrastructure.html. This is getting spooky :)

  • http://code.google.com/p/jmockit Rogério Liesenfeld

    I am with “mike” on this.

    If you are writing integration tests, then let them use the real thing (Hibernate in this case) and hit the database.

    In unit tests, OTOH, I would always directly mock the library (the EntityManager interface). All Java libraries are mockable, so there is no need to wrap any of them.

    The true “world of pain” is having to create (and maintain) a lot of extra production code with no business or technical value, when you could write simple and direct tests instead.

  • http://blog.typemock.com Gil Zilberfeld

    Hi Mark,

    In our latest installment of our webcast This week in testing, we talked about your (and Liz’s) post. I invite you to check it out, comment and if you really like what you see, and want to see more, spread the word.

    Gil Zilberfeld, Typemock

  • Pingback: TypeMock gets it wrong on ORM « On the Heap

  • Pingback: Episode 7 – Survivors | Marcelo Costa

  • Pingback: WYTIWYR : What You Test Is What You Run « Antonio's Blog

  • Pingback: A roadmap for unit testing « Early and Often