【问题标题】:How to reload a variable defined by let如何重新加载由 let 定义的变量
【发布时间】:2015-02-12 16:31:48
【问题描述】:

一个user 有很多comments,所以我想有一个工厂user 和一个comment 关联(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) 时,它会在我的test db 中创建user 和相关的comment

但是,我在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

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

【问题讨论】:

  • 如果在一个例子中需要.. 那么let 是完美的。我想是的。

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


【解决方案1】:

这与 let 是惰性求值的事实有关,并且您的用户工厂的注释是在创建用户之后添加的。

注意 let 是惰性求值的:直到第一次才求值 它定义的方法被调用。

请参阅 RSpec documentation 让和让!

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

【讨论】:

  • 我知道我的问题的原因,但你的回答没有提出任何解决方案....let 不会加载comment,因为评论是在user 之后创建的,所以我必须重新加载它。我正在寻找一种只重新加载一次的方法,而不是在每次测试之前
  • 嗯,对不起!似乎问题源于使用let,希望该信息至少对某人有用。我正在深入挖掘并尝试重新创建。我认为这里还有其他问题,因为我根据您的示例创建了一个简单的usercomment 和关联工厂,并且评论实际上没有重新加载。
【解决方案2】:

这个怎么样?

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

【讨论】:

  • 这不起作用,因为该方法已被记忆。 .reload 只会在第一次使用时运行。
  • 这不重要(事实上,更可取)——他们只需要重新加载用户一次,这样工厂中创建的评论就会出现。虽然实际上,更好的方法是在工厂本身中执行此操作,这样每次在测试中使用该工厂时,您不必还记得重新加载用户。
猜你喜欢
  • 2018-09-12
  • 2017-05-20
  • 2013-01-16
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2018-02-22
相关资源
最近更新 更多