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

问题描述 投票:0回答:3

一个

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)
时,它会在我的
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)
,但它会在每次测试之前创建
venda
comment

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

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

ruby-on-rails ruby rspec factory-bot
3个回答
0
投票

我在寻找有关如何重新加载 let 变量的另一个问题时看到了这一点,但在这里我认为可能的解决方案是让工厂使用关联本身而不是执行 after_create (不确定当问题出现时它是否可用)虽然被问到):

factory :user, class: User  do |t|
  ...
  factory :user_with_comment do
    # might need create(:comment) but in my testing build worked
    comments { [build(:comment)] }
  end
end
let(:user) { FactoryGirl.create(:user_with_comment) }
user.comments.size #=> 1

-2
投票

这与 let 是惰性计算的并且用户工厂的注释是在创建用户后添加的这一事实有关。

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

请参阅有关 let 和 let 的 RSpec 文档

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


-5
投票

这个怎么样?

let(:user) { FactoryGirl.create(:user_with_comment).reload }
© www.soinside.com 2019 - 2024. All rights reserved.