• Home
  • Blog
  • Community
  • Team
  • Products
  • Services
  • About

Text Post

Active Record Identity Map makes it easier to stub Model dependencies

Posted by tech-angels, November 11th

Problem

You want to write a unit test for this AccountController class. In order to test in isolation, you need to stub all the calls AccountController will make to models.

Because of the way ActiveRecord works, it’s tricky to write message expectations or stubs for an Account instance. You end up stubbing find and other AR methods, such as in the following example:

account = mock_model(Account, :id => "37")
Account.stub(:find).with("37") { account }
account.should_receive(:close)
post :close, :account_id => "37"

The problem is that approach leads to fragile tests due to the nature of ActiveRecord Query API. There is almost an “infinite” way of retrieving models. Whenever you change the way you retrieve the model, you’ll need to change your stubbing. For more information, I strongly recommend Avdi Grimm book’s Object on Rails.

IdentityMap to the rescue!

before(:all) { ActiveRecord::IdentityMap.enabled = true }
after(:all) { ActiveRecord::IdentityMap.enabled = false }

account = Factory(:account)
account.should_receive(:close)
post :close, :account_id => account.id

ActiveRecord::IdentityMap ensures that each object gets loaded only once by keeping every loaded object in a map.

When the AccountController retrieves an account, we can be sure it will be exactly the same object as in our test.

One drawback is a slower test. We are now creating an account in the DB only to benefit from Identity Map. It’s a trade off, we hope that more robust tests will save some time in the long run.

An alternative is to use any_instance stubbing, such as:

Account.any_instance.stub :close

But then, we loose the message expectation part and need to test something else. This approach could have side effects. As the name says, any instance of Account is stubbed!

What do you think?

Happy specing!

#rspec#testing#IdentityMap#rails

1 note
  1. buy-steroids-uk-co likes this
  2. tech-angels posted this
blog comments powered by Disqus
Share Share

Popular issues

People We Follow

  • Tumblr Staff
  • code code code
  • giant robots smashing into other giant robots
  • (:title "Technotalk")
  • Édouard Brière
  • The Changelog
  • Digital Wanderings
  • Airbrake Status

Popular Tags

Need to contact us?

You can join us on our social media space.

Tweet
  • Follow us on facebook
  • Follow us on twitter
  • Contact us by Mail