I’m watching Francis Hwang’s talk from RubyConf 2008 titled “Testing Heresies.” He discusses his reasons for not using mock objects, and commits a common error when trashing mocks: he shows crappy examples which evidently serve as proof of why the technique sucks.
To start, let’s look at the two main arguments people make for why mocks suck:
- They duplicate the code under test
- Objects can get out of sync when interfaces change
Here’s a code example Francis gives that uses mocks:
Before he gets into it, he says something along the lines of “Please let me know if I’m mischaracterizing the approach.” Too bad I wasn’t there. Yes, you COMPLETELY mischaracterized the approach.
If you’re using mocks like this, you’re doing it wrong. Very, very wrong. Here’s how you would really use mocks:
Then you would have a model level spec:
This is one example where I’ll cave in to the whole “mocks duplicate the code under test” argument. If your mocking code sucks, and your mocking code duplicates your production code, then guess what? Your production code sucks!
The value that mocking provides in this case is writing the code you wish you had. Do you really wish you had a find(:select => …, :conditions => …) in your controller code? Of course not! (I hope not, anyway). You don’t have to use mocks to get the APIs you want (refactoring is still an option but it’s very, very helpful.
Bottom line: mocks aren’t inherently evil. I could take Francis’s example as proof of why Ruby, Rails, and RSpec all suck, and it would be just as valid as concluding that mocks suck. The only things that sucked here are the example and the production code.
Code gets out of sync
No it doesn’t. Let me give you a very quick rundown of the code you would write to implement this feature.
1. Write a cucumber feature
2. Write the controller spec, mocking out the finder, implement controller
3. Write model specs for the finder, implement finder
Now when someone says “but if I rename the finder, the controller spec will continue to pass! Mocks are horrible!!” You can point to the acceptance test that fails. Holy quality software, batman!
You know that folder you’ve got filled with coding projects that never made it off the ground?
- code snippets that could become libraries, with a few tests
- libraries that could become gems, with some new documentation
- gems that could become side projects, with a bit of refactoring
- side projects that could become products, with the right game plan
You start each project with the best intentions, even big plans for some of them… but then life gets in the way, and you focus your attention on more important things. Then when you get some free time you dream up another project, and the cycle repeats itself.
You know that you can ship – you get all kinds of other projects out the door at work. Why do your open source ideas collect dust and regret?
The rules you apply to get stuff done at work don’t apply to your hobby projects. If you take the objective-driven approach you use in your work and try to use it on your hobby projects, you will continue to fall short of your goals – and keep piling on the guilt.
You can break the cycle, by launching one of your open source project ideas. You can push the spiral upward, by getting one project out the door and moving on to the next one.
You just need to learn a few skills and techniques that will help you dig in to your project graveyard and bring your projects to life.
Get Hack Your Open Source Project for FREE and you will: