Search code examples
ruby-on-railsunit-testingruby-on-rails-3.2minitestcounter-cache

How can I ensure that counter_cache is updated correctly in rails unit tests?


I've got a normal counter_cache set up for my Rails 3.2.6 model. It works flawlessly in the webapp, but fails in unit tests.

The following snippet illustrates the issue at hand:

test "counter_cache ..." do
    u = FactoryGirl.create(:customer)
    FactoryGirl.create(:order, :customer => u)

    # u.orders.count == 1; rest is always 0
    assert_equal u.orders.count, u.orders_count  # FAILS!
    assert_equal u.orders.count, u.orders.size   # FAILS!
    assert_equal u.orders.count, u.orders.length # FAILS!
end

Note that I tried the same without the use of FactoryGirl, which still failed.

How can I ensure that counter_cache is updated correctly in unit tests?


Solution

  • The problem is that u doesn't know that an order was created that belongs to it, so it hasn't updated its state to reflect that. You have at least two options:

    • reload the User instance (u) after creating the order, since it doesn't know that an Order was added:

      u.reload
      
    • Create the Order through the User:

      u.orders << FactoryGirl.build(:order)
      

      (This one may be a bit finicky if you have an after_create, or even if you don't—FactoryGirl can do too much and screw things up sometimes).