I’ve had a rocky relationship with mocking in ruby tests. It went something like this:
- Discover testing. Is neat!
- Discover rspec, mocking, and the isolation of my model and controller tests. Is super neat!
- Discover the pain of refactoring when I have tons of expectations, each with long and specific lists of parameters that must be passed.
- Associate “mocking” with “testing the implementation and not the behavior”. Deem it an evil practice. Rant about it excessively.
Several months ago I had the pleasure of pairing with Corey Haines. During these sessions he helped me realize this: mocking got me all mad because it was trying to tell me that I was writing bad code. I was testing the implementation and not the behavior, but that’s because my implementation was yucky and therefore too hard to test properly. Something Corey said wrapped this up very nicely for me: Well designed code is code that is easy to test.
So if I’m writing something like this in my test:
Product.should_receive(:find).with(:all, :conditions => { :active => true },
rder => "position ASC").returns(products)
That should be a red flag. It’s gross. But mocking isn’t to blame. It’s gross because the code in my controller is gross.
This is why writing the test first helps. When I write my test, I’m writing the code I wish I had. I want to write the easiest code possible, so I should write the simplest test possible. The line above should read more like:
Product.stub!(:active).returns(products)
Writing short concise tests leads to short, concise implementation.
Other Posts That Might Interest You




