2012-07-11 17 views
8

FactoryGirlに私の名前を生成させようとしていますが、シーケンスがインクリメントしていないようです。スペック出力はファクトリーガールシーケンスがインクリメントしない

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" 

# 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 

ありますなぜFactoryGirlは仕様書に一連の名前を生成しないのですか?

答えて

12

動作することは、それが後のビルドフックは常に任意の名前を実行して、上書きされますので、あなたが、スペックのどこにでも名前を上書きすることができないことを意味しますビット。

元の例が機能しないのは、ファクトリの実行時ではなく、ファクトリが定義されているときにシーケンスを呼び出すためです。ファクトリが実行されるたびに呼び出される属性定義にブロックを提供できます。このようにして、すべてのインスタンスに対して1つの値を生成するのではなく、各インスタンスの値を生成する機会が得られます。これは、シーケンスと時間に最も頻繁に使用されます。あなたはこのスニペットを使用して元の例を修正することができます

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 

しかし、異なるファクトリに対して異なる名前形式が必要な場合は、これは機能しません。

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 
関連する問題