0

I met a very strange issue when writing test using RSpec. Assume that I have 2 models: Company and Item with association company has_many items. I also set up database_cleaner with strategy transaction. My RSpec version is 2.13.0, database_cleaner version is 1.0.1, rails version is 3.2.15, factory_girl version is 4.2.0. Here is my test:

let(:company) { RSpec.configuration.company }
context "has accounts" do
  it "returns true" do
    company.items << FactoryGirl.create(:item)
    company.items.count.should > 0
  end
end
context "does not have accounts" do
  it "returns false" do
    company.items.count.should == 0
  end
end

end

I set up an initial company to rspec configuration for using in every test because I don't want to recreate it in every tests because creating a company takes a lot of time(due to its callbacks and validations). The second test fails because item is not cleaned from the database after the first test. I don't understand why. If I change line company.items << FactoryGirl.create(:item) to FactoryGirl.create(:item, company: company), the it passes. So can any body explain for me why transaction isn't rollbacked in the first situation. I'm really messed up

Thanks. I really appreciate.

pawel7318
  • 3,383
  • 2
  • 28
  • 44

1 Answers1

0

I think the problem is not in the rollback and I'm wondering if company.items can store it's value between contexts but I'm not sure.

I'm unable to reproduce it quickly so I want to ask you to:

  1. check log/test.log when the rollback is performed
  2. how many INSERTs was made for company.items << FactoryGirl.create(:item)
  3. than change on the first test > to < that way: company.items.count.should < 0 it'll make test to fail but you'll get count value. Is it 1 or 2 ?
  4. If you have relation between Company and Item model like has_many/belongs_to than I would suggest to just use build(:item) which should create company for it as well:

for example:

let(:item) { FactoryGirl.build(:item) }
context "has accounts"
it "returns true" do
  item.save
  Company.items.count.should == 1
end

don't forget to include association :company line at :item's factory

Hint:

add to spec_helper.rb:

RSpec.configure do |config|
  # most omitted
  config.include FactoryGirl::Syntax::Methods

and you can call any FactoryGirl method directly like this:

let(:item) { build(:item) }
pawel7318
  • 3,383
  • 2
  • 28
  • 44