2012-01-30 8 views
20

Casi cada archivo de especificaciones llego al otro lado me acaban de escribir cosas como:¿Debo colgar el modelo en Factory girl o en el archivo de especificaciones durante la prueba?

before :each do 
    @cimg = Factory.build :cimg_valid 
    @cimg.stub(:validate_img).and_return true 
    @cimg.stub(:validate_img_url).and_return true 
    @cimg.stub(:save_images).and_return true 
    @cimg.stub(:process_image).and_return true 
    @cimg.stub(:img).and_return true 
    end 

Es decir, el modelo que recibo de Factory.build es completamente válido. Pero si yo no golpeo eso se ahorra cosas en el sistema de archivos, y valida cosas que no estoy probando ...

Lo que quiero decir, yo creo que sería más limpio que hacer algo como esto:

before :each do 
    @cimg = Factory.build :cimg_for_testing_tags 
    end 

Si es posible anular dentro de la fábrica.

¿Cuál es la forma correcta de colgar el modelo?

Respuesta

20

En versiones recientes de factory_girl tiene una devolución de llamada after_build, por lo que cree que podría definir su fábrica de la siguiente manera:

FactoryGirl.define do 
    factory :cimg_for_testing_tags do 

    ... # Factory attributes 

    after_build do |cimg| 
     cimg.stub(:validate_img).and_return true 
    end 
    end 
end 

ACTUALIZACIÓN

Después factory_girl 3.3.0, la sintaxis ha cambiado para seguir:

FactoryGirl.define do 
    factory :cimg_for_testing_tags do 

    ... # Factory attributes 

    after(:build) do |cimg| 
     cimg.stub(:validate_img).and_return true 
    end 
    end 
end 
+3

Pero * ¿Debería hacerlo *? ¿O debería insertarlo en el archivo de especificaciones? – Zequez

+2

Creo que si se repite muchas veces, tener un stub general tiene sentido en este caso, solo asegúrese de que: cimg_for_testing_tags tenga una fábrica principal que no se apague para las situaciones en las que desea probar el comportamiento real. – fkreusch

+0

Esta es una técnica increíble. Me he encontrado luchando con una solución para este tipo de situaciones. Gracias @fkreusch! – josemota

25

@ respuesta de fkreusch funciona muy bien hasta que utilice la nueva sintaxis RSpec expect() (3.0+)

Su puesta en rails_helper.rb funciona para mí:

FactoryGirl::SyntaxRunner.class_eval do 
    include RSpec::Mocks::ExampleMethods 
end 

En el ejemplo de la OP, ahora se puede hacer:

FactoryGirl.define do 
    factory :cimg_for_testing_tags do 

    ... # Factory attributes 

    after(:build) do |cimg| 
     allow(cimg).to receive(:validate_img) { true } 
    end 
    end 
end 

crédito: github.com/printercu, consulte: https://github.com/thoughtbot/factory_girl/issues/703#issuecomment-83960003

+3

Al hacer lo que aquí se describe, se genera el siguiente error (FactoryGirl v4.7.0): '' 'No se admite el uso de dobles o dobles parciales de rspec-mocks fuera del ciclo de vida por prueba. '' ' – jsears

+0

@jsears Me encontré con ese error porque mi' rails_helper.rb' estaba ejecutando 'FactoryGirl.lint' en un bloque' before (: suite) ', y los stubs no se pueden configurar allí. Resolví el problema envolviendo la llamada de pelusa en 'RSpec :: Mocks.with_temporary_scope {...}'. – vergenzt

+0

Tenga en cuenta que 'FactoryGirl' ahora es' FactoryBot', por lo que esos dos nombres deberían cambiar en su ejemplo. – aardvarkk

1

Una fábrica debe producir objetos del "mundo real", por lo tanto, es una mala práctica (y propensa a errores) cambiar el comportamiento (es decir, stub) en una fábrica.

Usted puede hacer

let(:user) instance_double(User, FactoryGirl.attributes_for(:user)) 

before do 
    allow(user).to receive(:something).and_return('something') 
end 

y si su cláusula de before se hace demasiado grande es posible que desee extraerlo a un método separado o crear una clase hija maqueta que anula métodos que desee trozo.

Cuestiones relacionadas