Amazon

Friday, October 16, 2009

Unit Test: Take Two, with factory_girl + Mocha

In my day job, I occasionally interface with a group of Java developers, who pride themselves in doing a darn good job of testing their own code. We are talking about unit tests, functional tests, continuous integration tests, the whole shebang.

I learnt about mocking from them (and was the target of many such jokes, e.g. "So, here to be mocked some more?"), and decided to try out some mocking frameworks for .NET, but am having time comprehending the role of mock objects in testing. However, recently I was reading Recipe #55 in Advanced Rails Recipes, and was inspired.

So when I took my reading to the web, largely driven/led by Google, I realized that mocha is another mocking framework that some prefer over flexmock. I looked into it a bit, and decided that it is for me.

Now, like many, I have come to dislike fixtures for complex test cases where multiple instances of multiple models are involved. But I do believe that fixtures have a role. The way I look at it, if you find that you set up the same data over and over again in your tests, maybe it's time to push them into fixtures.

Anyhow, instead of using fixtures, I have been using ThoughtBot's factory_girl to create my test objects, and am loving it.

Furthermore, someone challenged me to rip out all my test code and re-write them since they are woefully out-of-date and no longer pass. But part of my failure to keep my test code fresh was due to frustration with fixtures.

So now, armed with factory_girl and Mocha, I wiped my test slate clean (removed almost all my test code and fixtures), and am starting over.

To start things off, I decided to do something akin to that recipe in the ARR book, like so:
# test/unit/project_test.rb

require 'test_helper'
require 'mocha'

class ProjectTest < ActiveSupport::TestCase

test "create" do
p = Factory.build(:project)
assert p.valid?
end

test "use mocha to simulate failure" do
p = Factory.build(:project)
p.expects(:valid?).returns(false)
assert p.invalid?
end

end
Now let's run it:
% rake test:units
----- <snipped> -----
Started
........................
Finished in 0.179492 seconds.

24 tests, 41 assertions, 0 failures, 0 errors
Nice! Of course I am not yet certain how mocking applies to unit tests, but I will forge ahead and see how things go.

No comments: