Using Mocha to test Rails associations, and association dependencies
I just started using Mocha to mock and stub some of my rails tests, after finding out first-hand that fixtures suck and indeed need fixin'. Here's what I like about Mocha:
- Easy to use
- Easy to read
- Decreases the need for complexly dependant fixtures
- Speeds up tests once fixtures are removed
Not only that, but Mocha puts some constraints on your tests that force you to be a better tester. If you mock and stub instead of using fixtures, you need to build your tests up to a complete test from an empty mock, rather than whittling them down from a full Ruby object with lots of data. For example,
def test_items_should_return_uniq_set_of_all_rentals_items bob = Renter.new bob.expects(:rentals).returns([stub(:items => [:item_1, :item_2, :item_3]), stub(:items => [:item_3, :item_4, :item_5])]) assert_equal bob.items, [:item_1, :item_2, :item_3, :item_4, :item_5] end
Before I might have been tempted to play with the +Item+ objects, but with Mocha, they are just symbols, so the test is more transparent.
I am still grappling with some aspects of Mocha and testing in general. Like custom SQL. If you want to test your custom SQL, you need data in the database at some point. Its seems like the higher level stuff is better for mocking, and the lower level stuff gets a little trickier. Here is how I tackled testing a ActiveRecord association, and its dependency:
require File.dirname(__FILE__) + '/../test_helper' class RenterTest < Test::Unit::TestCase def test_rental_association bob = Renter.new bob.rentals << Rental.new assert !bob.rentals.empty? end def test_rental_dependency bob = Renter.new bob.rentals << Rental.new bob.rentals.first.expects(:destroy) bob.destroy end end
Railscasts can get you started.
technorati tags:ruby, rails, testing, mock, test, mocha
Blogged with Flock