[rspec-users] Specifying mocks

Tom Stuart tom at experthuman.com
Fri May 29 05:11:56 EDT 2009


Hi,

One of the problems with mocks, as far as I can tell, is that they  
might go out of sync with the real object they're mocking. Is it  
possible and sane to detect this by running each spec against its  
corresponding mock? Does anyone already do this?

For example: your Account object has a particular behavioural  
specification; you perhaps have some convenient helper method for  
creating a mock Account which conforms to that specification with  
various stubbed responses; and the specifications of other objects use  
that mock Account when describing behaviours which involve interaction  
with Accounts. What happens when you want to change the behaviour of  
Account? Naively, you update the specification and implementation of  
Account, your specs all pass, and you think you're done, except you're  
not: the Account mock is now misrepresenting the behaviour of Account  
all over the system, with the result that you've got failures that the  
specs don't reveal.

Of course you have integration tests that will show these failures at  
a higher level but it doesn't feel fundamentally like a problem that  
RSpec has no business solving. Why not establish a base case for  
RSpec's inductive demonstration of correctness by running the Account  
spec against the standard Account mock? That way you'll automatically  
be told, by RSpec, whenever the actual behaviour of your mock doesn't  
match the specified behaviour of the mocked object, and you can let  
your integration tests concentrate on the hard stuff (stateful  
interactions between many objects) instead of checking that you  
haven't forgotten to keep your specs up-to-date.

This assumes a priori that it makes engineering sense to have a  
globally-available DRY mock helper for each object (i.e. class) rather  
than building up your mocks piecemeal in every spec; I've found that I  
always start off a project by doing the latter but end up refactoring  
into the former once I get sick of mocking the same stuff over and  
over again. Maybe that's the wrong way to do things altogether, or  
maybe this is a process issue that I've misunderstood (i.e. the answer  
is always to use integration tests to detect this kind of failure), so  
stop me if I'm being stupid.

Cheers,
-Tom


More information about the rspec-users mailing list