ruby-on-rails - FactoryGirl 如何创建一个由关联回调创建的实例

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

考虑两种模型:

class User < ActiveRecord::Base

  has_one :book

  after_create :create_book
end

class Book < ActiveRecord::Base
  belongs_to :user

  validate_uniqueness :user_id
end

每个用户可以拥有并且只能拥有一本书。然后我在我的规范中定义了两个工厂:

factory :user do
end

factory book do
  user
end

那么问题来了,当我为 Book 编写测试时, 我想创建一条记录 book1 (我们称它为)Book , 当我使用 FactoryGirl.create(:book) .它将创建 Book 的实例然后尝试创建关联定义 user .创建用户后,after_create是触发器,book2user 创建.然后它尝试绑定(bind) book1user并被唯一性关联阻止。

现在我正在使用 book = FactoryGirl.create(:user).book .这是最好/正确的方法吗?我认为它很直观,因为我正在测试 Book , 我认为最好有 book = FactoryGirl.create(:book)

非常感谢。

最佳答案

我认为我们可以为此使用trait。这是示例:

工厂

factory :user do
  # Your config here

  # Use trait
  trait :without_book do
    after(:build) do |user|
      allow(user).to receive(:create_book).and_return true
    end
  end

  trait :with_book do
    allow(user).to receive(:create_book).and_call_original
  end

  transient do
     # Use this by default but don't use this line also works
     # because we create book in the normal behavior
     with_book
  end
end

规范

context 'test user without book' do
  let(:user) { FactoryGirl.create(:user, :without_book)

  it 'blah blah' do
  end
end

context 'test user with book' do
  let(:user) { FactoryGirl.create(:user, :with_book)
  # Or simply use this, because :with_book is default
  # let(:user) { FactoryGirl.create(:user)

  it 'blah blah' do
  end
end

顺便说一句,如你所见,我在 allow(user).to receive(:create_book).and_return true 处使用了一个 stub 方法,基本上,这个实用方法来自 rspec-mock ,我们需要此配置以使其在工厂中可用:

spec/rails_helper.rb

FactoryGirl::SyntaxRunner.class_eval do
  include RSpec::Mocks::ExampleMethods
end

理想情况下,您可以通过为用户使用trait来处理创建不创建一本书,这样会更容易模拟场景!

关于ruby-on-rails - FactoryGirl 如何创建一个由关联回调创建的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37538451/

相关文章:

css - 如何使用 css-modules 在网站上调整 Capybara finders?

ruby-on-rails - 如何在 Rails 4 中使用 @font-face 嵌入字体?

ruby-on-rails - 将 update_attributes 与列类型的数组一起使用

testing - 我如何从 testcafe 框架自定义 testRunner?

python - PyTest:测试if语句中调用了哪个函数

ruby-on-rails - rspec + 应该 : setting up data

mySQL "Too many connections"错误受杂种实例数的影响?

ruby-on-rails - 在 Rails 应用程序中请求/响应 Soap API

javascript - 如何在 Jest 中访问局部变量

ruby-on-rails - 分别使用 Cucumber 和 Rspec 如何测试以及测试什么?