在 "let" 中定义 "child" 个变量

Defining a "child" variables in "let"

我有 2 个模型要测试:文章和用户。用户 has_many 篇文章。在其中一个测试用例中,我定义了一个变量:

context 'some context' do
  let(:my_user) { FactoryGirl.create(:user) } 

如何创建属于那个 my_user 的 100 篇文章?我试过这个:

let(:my_user) { FactoryGirl.create(:user, articles: [build(:article)]) } # error

  # or
  let(:article) { FactoryGirl.create(:article, user: my_user) } # doesn't work
  it 'fdsfdsfs' do
    # my_user.articles still has no articles
  end

但没有成功。

您可以使用回调在工厂本身中执行此操作,也可以使用 create_list 执行此操作,如下所示:

  let!(:user) { FactoryGirl.create(:user) }
  let!(:article) { FactoryGirl.create_list(:article, 100, user: user) }

我在这里使用 let! 这可能不是必需的,但是因为您没有显示整个测试,所以我无法确定是否所有内容都被延迟加载。

要使用回调来实现,我喜欢这样做:

FactoryGirl.define do
  factory :user do
    sequence(:email) { |n| "user#{n}@email.com" }
    password 'password'

    factory :user_with_articles do
      after(:create) do |user|
        create_list(:article, 100, user: user)
      end
    end
  end
end

现在在你的测试中你可以做

let(:user) { FactoryGirl.create(:user_with_articles) }

这将创建一个拥有 100 篇文章的用户。

作为很好的答案 的补充,您的第一次尝试似乎失败了,因为您试图调用 FactoryGirl.build 而没有限定对 build 的引用,而您的第二次尝试失败了因为 let(:article) 被延迟评估并且您从未在测试中引用 article,导致文章永远不会与您的用户相关联。