Should you only mock types you own?
I read through TDD: Only mock types you own entry by Mark Needham and would like to know if this is best practice or not?
Please note that he is not against mocking, but against mocking directly - he does say that writing a wrapper and mocking that is fine.
Solution 1:
My answer is "no". You should mock anything that makes sense in the context of a given unit test. It should not matter if you "own" the mocked type or not.
These days, in a Java or .NET environment everything (and I really mean everything) can be easily mocked. So, there is no technical reason to go to the trouble of first writing extra wrapper code.
Some additional ideas I have been thinking about recently (November 2010), that show how illogical to "only mock types you own" can be:
- Suppose you do create a wrapper for a third-party API, and then you mock the wrapper in unit tests. Later, however, you figure the wrapper can be reused in another app, so you move it to a separate library. So now the wrapper is no longer "owned" by you (since it is used in multiple apps, potentially maintained by different teams). Should developers create a new wrapper for the old one?!? And keep doing it recursively, adding layer upon layer of essentially useless code?
- Suppose somebody else already created a nice wrapper for some non-trivial API and made it available as a reusable library. If said wrapper is just what I need for my specific use case, should I first create a wrapper for the wrapper, with a nearly identical API, just so I will "own" it?!?
For a concrete and realistic example, consider the Apache Commons Email API, which is nothing more than a wrapper for the standard Java Mail API. Since I don't own it, should I always create a wrapper for the Commons Email API, whenever I write unit tests for a class which needs to send e-mail?
Solution 2:
Depends whether you mean mock or mock™…
Given you are just using a mock framework (as eg Mockito) to create stubs, then creating stubs of types you don't own is totally okay and reasonable.
If however, you are using a mock framework (as eg Mockito) to create mock™ objects, then you best literally follow the advice of the mock™ evangelists. Personally I lost touch to that movement, so I cannot tell you whether Mark Needham's advice is to be considered kosher or not.
Irony aside, what Mark writes about mocking of EntityManagers
in Hibernate sounds reasonable by itself. But I doubt that we can generalize a rule like "never mock types you don't own" from that specific case. Sometime it might make sense, sometimes not.
Solution 3:
I like the explanation the Mockito project gives to this question.
Don't mock type you don't own!
This is not a hard line, but crossing this line may have repercussions! (it most likely will)
- Imagine code that mocks a third party lib. After a particular upgrade of a third library, the logic might change a bit, but the test suite will execute just fine, because it's mocked. So later on, thinking everything is good to go, the build-wall is green after all, the software is deployed and... Boom
- It may be a sign that the current design is not decoupled enough from this third party library.
- Also another issue is that the third party lib might be complex and require a lot of mocks to even work properly. That leads to overly specified tests and complex fixtures, which in itself compromises the compact and readable goal. Or to tests which do not cover the code enough, because of the complexity to mock the external system.
Instead, the most common way is to create wrappers around the external lib/system, though one should be aware of the risk of abstraction leakage, where too much low level API, concepts or exceptions, goes beyond the boundary of the wrapper. In order to verify integration with the third party library, write integration tests, and make them as compact and readable as possible as well.
Solution 4:
I was going to say "no" but having had a quick look at the blog post I can see what he is on about.
He talks specifically about mocking EntityManagers in Hibernate. I am against this. EntityManagers should be hidden inside DAOs (or similar) and the DAOs are what should be mocked. Testing one line calls to EntityManager is a complete waste of your time and will break as soon as anything changes.
But if you do have third party code that you want to test how you interact with it, by all means.