Reputation: 8900
I have a simple situation setup in order to learn testing with FactoryGirl. A Bank has many transactions. Each time a transaction is created, it should subtract the transaction amount from the bank's total.
Here is the code:
# Bank.rb - Has many transactions
class Bank < ActiveRecord::Base
has_many :transactions
end
# Transaction.rb - Belongs to a bank and should decrement the bank's total when created.
class Transaction < ActiveRecord::Base
belongs_to :bank
after_create :decrement_bank_amount
def decrement_bank_amount
bank.decrement!(:amount, amount) if bank
end
end
# factories.rb - Create default factories for testing. This is FactoryGirl 4 syntax
FactoryGirl.define do
factory :bank do
sequence(:name) { |n| 'Bank ' + n.to_s }
end
factory :transaction do
sequence(:title) { |n| 'Payment ' + n.to_s }
bank
end
end
# Transaction_spec.rb - Creates a bank and a transaction.
require 'spec_helper'
describe Transaction do
describe ".create" do
context "when a bank is set" do
it "decreases the bank's amount" do
bank = FactoryGirl.create(:bank, :amount => 1000) do |b|
b.transactions.create(:amount => 250)
end
bank.amount.to_i.should eq 750
end
end
end
end
The test keeps failing and the bank amount keeps returning 1000 instead of the expected 750. I'm stumped!
Upvotes: 5
Views: 1134
Reputation: 107718
This test is failing because bank
is fetched from the database and stored. The after_create
callback modifies the record in the database, but the object in bank
doesn't see that, and so isn't updated.
You're going to need to call reload
on that object before checking the amount:
bank.reload
bank.amount.to_i.should == 750
Upvotes: 7