我正在尝试让FactoryGirl为我生成一些名字,但序列似乎没有增加。
# spec/factories/vessel.rb
require 'factory_girl'
FactoryGirl.define do
sequence :vessel_name do |n|
"TK42#{n}"
end
factory :vessel do
name FactoryGirl.generate(:vessel_name)
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
end
end
# spec/models/vessel_spec.rb
require 'spec_helper'
describe Vessel do
context 'working in the factory' do
it 'makes a valid vessel' do
vessel = FactoryGirl.create(:vessel)
vessel.should be_valid, "Invalid vessel #{vessel.valid? || vessel.errors.messages.inspect}"
end
it 'makes another valid vessel' do
vessel = FactoryGirl.create(:vessel)
vessel.should be_valid, "Invalid vessel #{vessel.valid? || vessel.errors.messages.inspect}"
end
end
end
规格输出
Vessel
working in the factory
makes a valid vessel
makes another valid vessel (FAILED - 1)
Failures:
1) Vessel working in the factory makes another valid vessel
Failure/Error: vessel = FactoryGirl.create(:vessel)
ActiveRecord::RecordInvalid:
Validation failed: Name has already been taken
# ./spec/models/vessel_spec.rb:13:in `block (3 levels) in <top (required)>'
# app/models/vessel.rb
class Vessel < ActiveRecord::Base
attr_accessible :name, :vessel_type, :volume_scalar, :volume_units
validates :name, :presence => true, :uniqueness => true
end
0 HAL:0 work/nrb-brewery-management % bundle show factory_girl_rails rspec
/home/brundage/.rvm/gems/ruby-1.9.3-p0/gems/factory_girl_rails-3.5.0
/home/brundage/.rvm/gems/ruby-1.9.3-p0/gems/rspec-2.11.0
0 HAL:0 work/nrb-brewery-management % rails c test
Loading test environment (Rails 3.2.6)
1.9.3p0 :001 > FactoryGirl.generate :vessel_name
=> "TK422"
1.9.3p0 :002 > FactoryGirl.generate :vessel_name
=> "TK423"
1.9.3p0 :003 > FactoryGirl.generate :vessel_name
=> "TK424"
1.9.3p0 :004 > FactoryGirl.generate :vessel_name
=> "TK425"
为什么FactoryGirl不会在我的规范中生成一系列名称?
答案 0 :(得分:13)
这有效,这意味着你不能在规范中的任何地方覆盖名称,因为After build hook将始终运行并覆盖任何名称。
原始示例不起作用的原因是您在定义工厂时调用序列,而不是在运行工厂时调用序列。您可以为每次工厂运行时调用的属性定义提供一个块。这样,您就有机会为每个实例生成一个值,而不是为所有实例生成一个值。这最常用于序列和时间。
您可以使用此代码段修复原始示例:
sequence :vessel_name do |n|
"TK42#{n}"
end
factory :vessel do
name { generate(:vessel_name) }
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
end
如果可以使用相同的格式生成所有名称,您也可以通过重命名序列完全省略该值:
sequence :name do |n|
"TK42#{n}"
end
factory :vessel do
name
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
end
但是,如果您需要为不同的工厂使用不同的名称格式,那么这将无效。
答案 1 :(得分:2)
答案是:
require 'factory_girl'
FactoryGirl.define do
sequence :vessel_name do |n|
"TK42#{n}"
end
factory :vessel do
vessel_type 'fermenter'
volume_scalar 100.0
volume_units 'bbl'
after :build do |v|
v.name = FactoryGirl.generate(:vessel_name)
end
end
end