2012-07-11 4 views
8

Sto cercando di ottenere FactoryGirl per generare alcuni nomi per me, ma la sequenza non sembra aumentare.Sequenze di Factory Girl che non aumentano

# 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 

L'uscita specifica è

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" 

Perché FactoryGirl non genera una sequenza di nomi nella mia specifica?

risposta

12

che funziona, il bit vorrà dire che non si può ignorare il nome da nessuna parte nelle specifiche, perché il dopo gancio build sempre correre e sovrascrivere qualsiasi nome.

Il motivo per cui il tuo esempio originale non funziona è che stai invocando la sequenza quando la fabbrica è definita, piuttosto che quando viene eseguito il factory. È possibile fornire un blocco per attribuire definizioni che verranno invocate ogni volta che viene eseguito il factory. In questo modo, hai la possibilità di generare un valore per ogni istanza, piuttosto che generare un valore per tutte le istanze. Questo è più frequentemente usato per sequenze e tempi.

È possibile risolvere il tuo esempio originale con questo frammento:

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 

Se tutti i nomi possono essere generati con lo stesso formato, si potrebbe anche lasciare fuori il valore del tutto rinominando la sequenza:

sequence :name do |n| 
    "TK42#{n}" 
end 

factory :vessel do 
    name 
    vessel_type 'fermenter' 
    volume_scalar 100.0 
    volume_units 'bbl' 
end 

Tuttavia, questo non funzionerà se avete bisogno di formati di nome diversi per le diverse fabbriche.

2

E la risposta è:

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