Fed up with Rails fixtures? (part one)
In a previous post I explained why I’m not a big fan of Rails fixtures. But how can you avoid using them and still obtain good test coverage? Try forgetting about fixtures and writing unit tests that only test a single class and nothing else. Here’s an example where you hardly1 need to involve the database at all…
class Initial < ActiveRecord::Migration
def self.up
create_table :companies do |t|
t.column :name, :string
end
create_table :employees do |t|
t.column :company_id, :integer
t.column :salary, :integer
end
end
end
class Company < ActiveRecord::Base
has_many :employees
def wage_bill
employees.inject(0) { |total, employee| total + employee.salary }
end
end
class Employee < ActiveRecord::Base
belongs_to :company
end
So instead of writing this…
# companies.yml walmart: id: 1 name: Walmart
# employees.yml fred: id: 1 company_id: 1 salary: 10000 anne: id: 2 company_id: 1 salary: 20000
class CompanyTest < Test::Unit::TestCase
fixtures :companies, :employees
def test_should_calculate_wage_bill
assert_equal 30000, companies(:walmart).wage_bill
end
end
You can write this…
class CompanyTest < Test::Unit::TestCase
def test_should_calculate_wage_bill
employees = []
employees << Employee.new(:salary => 10000)
employees << Employee.new(:salary => 20000)
company = Company.new(:employees => employees)
assert_equal 10000 + 20000, company.wage_bill
end
end
This way you home in on the behaviour of the Company#wage_bill
method and avoid testing the ActiveRecord code and access to the database. More ways to avoid hitting the database will follow in another post.
1 ActiveRecord still needs to know what columns in each table e.g.
SHOW FIELDS FROM companies