Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does ActiveRecord make Ruby on Rails code hard to test?

I've spent most of my time in statically typed languages (primarily C#). I have some bad experiences with the Active Record pattern and unit testing, because of the static methods and the mix of entities and data access code.

Since the Ruby community probably is the most test driven of the communities out there, and the Rails ActiveRecord seems popular, there must be some way of combining TDD and ActiveRecord based code in Ruby on Rails.

I would guess that the problem goes away in dynamic languages, somehow, but I don't see how. So, what's the trick?

like image 763
Erik Öjebo Avatar asked Apr 01 '26 19:04

Erik Öjebo


1 Answers

The problem is that fixtures are horrible. A while ago I read an article called The Lie and it opened my eyes. This article focuses on Machinist, which I've used and liked, but currently I prefer factory_girl. Here's a basic example from their README:

You define a Factory with just enough default values to get your tests to pass:

# This will guess the User class
Factory.define :user do |u|
  u.first_name 'John'
  u.last_name  'Doe'
  u.admin false
end

And then in your tests you can override or add values as needed (contrived RSpec example)

describe User, "#is_admin?" do
  before(:each) do
    @user = Factory(:user, :admin => true, :email => '[email protected]')
  end

  it "should be true"
    @user.is_admin?.should be_true
  end
end

@user is now a real, live, working ActiveRecord model that lives (temporarily) in the test database. You can use factories in controller tests as well. You could mock them, but in my limited experience the effort is not worth the minor performance gain. Mostly I mock when I need to test a condition (save returning false even though the record is valid so that I can test the failing condition).

After using the two libraries mentioned here, you couldn't pay me to use fixtures again.

like image 102
Robert Speicher Avatar answered Apr 04 '26 09:04

Robert Speicher