Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FactoryGirl after_create method not saving

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!

like image 243
Wes Foster Avatar asked Feb 22 '13 02:02

Wes Foster


1 Answers

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
like image 147
Ryan Bigg Avatar answered Sep 30 '22 15:09

Ryan Bigg