如何重新加载let定义的变量

时间:2015-02-12 16:31:48

标签: ruby-on-rails ruby rspec factory-bot

user有很多comments,因此我希望工厂usercomment关联user_with_comment

factory :user, class: User  do |t|
  ...
  factory :user_with_comment do |t|
    after(:create) do |user|
      FactoryGirl.create(:comment, user_id: user.id)
    end
end

一切正常......当我致电FactoryGirl.create(:user_with_comment)时,它会在user中创建comment和相关的test db

但是,我在controller_spec

中遇到了一些问题

使用let我必须重新加载user才能看到comment

let(:user) { FactoryGirl.create(:user_with_comment) }
user.comments.size #=>0
user.reload
user.comments.size #=>1

一种解决方案是使用before(:each),但会在每次测试之前创建vendacomment

before(:each) do
  @user = FactoryGirl.create(:user_with_comment)
end
@user.comments.size #=>1

或者,我可以在每次测试之前重新加载user,但它也会打到数据库:

let(:user) { FactoryGirl.create(:user_with_comment) }
before(:each) do
  user.reload
end

在这种情况下,最好的方法是什么?

2 个答案:

答案 0 :(得分:-1)

这与以下事实有关:let是懒惰评估的,并且在创建用户后添加了用户工厂的注释。

  

请注意,let是惰性计算的:直到第一次才会计算它   调用它定义的方法。

请参阅let上的RSpec documentation并让!

使用let表示用户在第一次使用示例时创建的,因此在此之后创建注释。你可以用let!在每个示例之前创建用户以避免重新加载。如果您在规范中的所有/大多数示例中使用工厂,这不会对您的测试产生负面影响。

答案 1 :(得分:-4)

这个怎么样?

let(:user) { FactoryGirl.create(:user_with_comment).reload }