2012-07-11 10 views
8

Estoy intentando que FactoryGirl me genere algunos nombres, pero la secuencia no parece aumentar.Secuencias Factory Girl sin incrementar

# 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 

La salida spec es

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" 

¿Por qué FactoryGirl no genera una secuencia de nombres en mi especificación?

Respuesta

12

que funciona, el bit que significará que no se puede sobrescribir el nombre en cualquier lugar de las especificaciones, debido a que la acumulación después de gancho se ejecutará siempre y sobrescribir cualquier nombre.

El motivo por el que su ejemplo original no funciona es que está invocando la secuencia cuando se define la fábrica, en lugar de cuando se ejecuta la fábrica. Puede proporcionar un bloque para las definiciones de atributo que se invocarán cada vez que se ejecute la fábrica. De esta forma, tienes la oportunidad de generar un valor para cada instancia, en lugar de generar un valor para todas las instancias. Esto se usa con mayor frecuencia para secuencias y tiempos.

Usted puede fijar su ejemplo original con este fragmento:

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 

Si todos los nombres se pueden generar con el mismo formato, también se puede dejar de lado el valor en su totalidad por el cambio de nombre de su secuencia:

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

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

Sin embargo, eso no funcionará si necesita formatos de nombre diferentes para diferentes fábricas.

2

Y la respuesta es:

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 
Cuestiones relacionadas