Reputation: 3923
Here's my code snippet:
context "(3) Integration" do
let(:ad) { create(:ad) }
let(:property) { create(:property, owner_id: 1) }
let(:visitor_session) { create(:visitor_session, property_id: property.id) }
let(:impression) { create(:impression, ad_id: ad.id, visitor_session_id: visitor_session.id) }
# before(:each) do
# DatabaseCleaner.clean_with(:truncation)
# end
describe "(a) An ad can check it's impressions" do
it do
expect(ad.impressions).to include impression
end
end
describe "(b) An ad can check the total impression count" do
it do
expect(ad.impressions.count).to eq 1;
end
end
end
The second test fails, when it really should be passing, and I'm quite flabbergasted. If I pass binding.pry in the middle of the first test, the output for ad.impressions
returns a CollectionProxy:
#<ActiveRecord::Associations::CollectionProxy [#<Impression id: 1, start_at: "2014-12-05 17:17:40", duration: 10, is_valid: true, ad_id: 1, visitor_session_id: 1, created_at: "2014-12-05 17:17:49", updated_at: "2014-12-05 17:17:49">]>
Calling count on this, in the pry console, returns a value of 1.
When I get to the second test, ad
appears to be the same object as in the first test, except now its impressions CollectionProxy is an empty array.
I suspected it might be a database cleaning issue, which is why I commented it out, but it didn't seem to have any effect. Here's my spec_helper for those needed more details:
require 'factory_girl'
require 'database_cleaner'
require 'devise'
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :controller
config.include FactoryGirl::Syntax::Methods
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, :js => true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
config.color = true;
end
Why is my collection not persisting over to the second test?
Upvotes: 0
Views: 33
Reputation: 24367
The only reason the first test passes is that you are calling impression
directly within it, which cause the let(:impression) block to be evaluated - this creates the impression record the first time it is called.
Since the second test does not call impression
at all, that record never gets created.
To fix it use let!
which will evaluate the block before the test code itself:
let!(:impression) { create(:impression, ad_id: ad.id, visitor_session_id: visitor_session.id) }
See the let and let! documentation for more info.
Upvotes: 2