FactoryGirl和测试has_many与关联

时间:2015-11-25 11:03:27

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

我正在尝试运行一个简单的测试,检查是否可以使用其关联构建对象

class Portfolio < ActiveRecord::Base
  has_many :portfolio_sectors
  has_many :sectors, through: :portfolio_sectors
  has_many :portfolio_images, dependent: :destroy
  accepts_nested_attributes_for :portfolio_images, allow_destroy: true
end

class Sector < ActiveRecord::Base
  has_many :portfolio_sectors
  has_many :portfolios, through: :portfolio_sectors
end

我的测试看起来像这样

RSpec.describe Portfolio, type: :model do
  it 'should have a valid Factory' do
    expect(FactoryGirl.build(:portfolio)).to be_valid
  end
end

投资组合工厂看起来像

include ActionDispatch::TestProcess
FactoryGirl.define do
  factory :portfolio do |p|
    p.title 'Test portfolio title'
    p.overview 'test sentence for the overview section of portfolio'
    p.url 'http://bbc.co.uk'
    p.after(:create) do |portfolio|
      portfolio.sectors = FactoryGirl.create(:associated_sector, portfolio: portfolio)
    end
    p.after(:create) do |portfolio|
     portfolio.portfolio_images = [FactoryGirl.build(:portfolio_image, portfolio: portfolio)]
    end
 end
end

所以当这个测试运行时我得到了

Failure/Error: expect(FactoryGirl.build(:portfolio)).to be_valid
expected #<Portfolio id: nil,
           overview: "test sentence for the overview section of portfoli...", 
           title: "Test portfolio title",
           sector_id: nil, 
           url: "http://bbc.co.uk", 
           created_at: nil, 
           updated_at: nil> 
to be valid, but got errors: Sectors Choose At Least 1 Sector

我可以看到为什么没有扇区ID存在。

如何在创建投资组合时传递扇区ID?

或者我接近这个错误?

由于

1 个答案:

答案 0 :(得分:0)

您在此处重新定义create回调:

p.after(:create) do |portfolio|
  portfolio.sectors = FactoryGirl.create(:associated_sector, portfolio: portfolio)
end
p.after(:create) do |portfolio|
  portfolio.portfolio_images = [FactoryGirl.build(:portfolio_image, portfolio: portfolio)]
end

没有魔法,第二个重新定义第一个。使用后续电话:

p.after(:create) do |portfolio|
  portfolio.sectors = FactoryGirl.create(:associated_sector, portfolio: portfolio)
  portfolio.portfolio_images = [FactoryGirl.build(:portfolio_image, portfolio: portfolio)]
  portfolio.save!
end