这是我的代码段:
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
第二次测试失败了,当真的应该通过时,我非常惊讶。如果我在第一次测试的中间传递binding.pry,ad.impressions
的输出将返回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">]>
在pry控制台中调用count,返回值1.
当我进行第二次测试时,ad
似乎与第一次测试中的对象相同,除了现在它的印象CollectionProxy是一个空数组。
我怀疑它可能是一个数据库清理问题,这就是我评论它的原因,但它似乎没有任何影响。这是我需要更多细节的spec_helper:
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
为什么我的收藏品没有持续到第二次测试?
答案 0 :(得分:2)
第一次测试通过的唯一原因是您直接在其中调用impression
,这会导致评估let(:impression)块 - 这会在第一次调用时创建印象记录。
由于第二次测试根本没有调用impression
,因此永远不会创建该记录。
要修复它,请使用let!
来评估测试代码本身之前的块:
let!(:impression) { create(:impression, ad_id: ad.id, visitor_session_id: visitor_session.id) }
有关详细信息,请参阅let and let!文档。