One of my TDD weaknesses: mock objects for complex objects

April 27, 2009

I am not really tuned in to test driven development yet, although I've written some programs that way (and found them quite valuable). As a result, I have some weaknesses, some TDD things that I just haven't acclimatized to yet. One of them is mock objects, specifically mock versions of complex objects; I don't like them and thus I don't use them. In trying to understand my dislike of them, I think that they seem too complex and fragile for at least two reasons.

First, how do I know that I've got the behavior of the mock objects correct? By definition, the complex objects generally have complex behavior, which can easily mean that the mock versions also need relatively complex behavior, which opens up the possibility of bugs. Second, how do I know that the mock objects are still behaving the same as the real objects? If I change the behavior of the real ones (complete with changing their unit tests to match), I may or may not remember the mock versions, and I may or may not realize that the change I made should change the mock version's responses in some way.

Both of these make me feel that mock versions of complex objects are fragile. I don't like fragile tests; they're a recipe for problems and frustrations, and at least in my state of TDD awareness, frustrations can easily lead to abandoning tests entirely. My current solution is to use more or less real objects but to have a unittest test ordering that matches the bottom up dependencies of the program. If early unittests fail, I know that it is pointless to go on; higher levels of code would just see a whole series of cascade failures as things malfunction underneath them.

(It is possible that part of my problem here is that I am confusing unit tests with some other sort of testing, functional or integration or end to end tests, as a result of having only an informal exposure to TDD.)


Comments on this page:

From 76.10.173.95 at 2009-04-27 23:40:55:

I think if you have problem making a simple mock object, you just don't have an interface that lends itself well to mocking, so to speak.

I tend to limit mock objects to interfaces that are simple, such that it doesn't matter how the implementation works. Usually the mock object will return hard coded data that is specific to the code being tested, not the code being mocked.

I also only really use them to substitute for things that are hard to reproduce in a unit test (like depending on some large external system on the network). Otherwise, I agree with your bottom-up strategy, which has the added bonus that the underlying code, which probably has a stable api, gets extra tests for free.

From 213.168.110.70 at 2009-04-28 17:32:54:

That's exactly what I discussed last week with a friend. We both told our experience with Mock objects and came to the conclusion that you usually test the Mock object or adapt your test to the Mock object. But in most cases, you will not test what you want to test, especially after the next iteration of development.

Written on 27 April 2009.
« The problems of over-documenting things
Pragmatic issues with hash verifiers for email messages »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Apr 27 22:05:33 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.