2012-02-17 10 views
49

Estoy utilizando Factory Girl para crear dos instancias en mi prueba de modelo/unidad para un grupo. Estoy probando el modelo para comprobar que una llamada a .Current sólo devuelve los grupos actuales de acuerdo con el atributo de caducidad según abajo ...Factory-girl create que pasa por alto la validación de mi modelo

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group, :expiry => Time.now + 1.week) } 
    let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 

    specify { Group.current.should == [current_group] } 
    end 

Mi problema es que tengo la validación en el modelo que verifica el vencimiento de un nuevo grupo es posterior a la fecha de hoy. Esto plantea la falla de validación a continuación.

1) Group.current 
    Failure/Error: let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 
    ActiveRecord::RecordInvalid: 
     Validation failed: Expiry is before todays date 

¿Hay alguna manera de crear el Grupo con fuerza o evitar la validación al crear con Factory Girl?

Respuesta

62

Esto no es muy específico para factorygirl, pero siempre se puede pasar por alto las validaciones al guardar los modelos a través de save(:validate => false):

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group) } 
    let!(:old_group) { 
    g = FactoryGirl.build(:group, :expiry => Time.now - 3.days) 
    g.save(:validate => false) 
    g 
    } 

    specify { Group.current.should == [current_group] } 
end 
+0

eso es exactamente lo que estaba buscando, gracias! – Norto23

+0

Consulte la respuesta de Jason Denney a continuación para obtener una mejor solución. –

5

Para este caso específico validación de fechas-baesd, también se puede utilizar la gema timecop de forma temporal modifique el tiempo para simular el registro anterior creado en el pasado.

1

Dependiendo de su situación, podría cambiar la validación para que ocurra solo en la actualización. Ejemplo: :validates :expire_date, :presence => true, :on => [:update ]

46

Prefiero esta solución de https://github.com/thoughtbot/factory_girl/issues/578.

Dentro de la fábrica:

to_create {|instance| instance.save(validate: false) } 
+4

Esta es una solución mucho más elegante que la aceptada. –

+3

Tenga en cuenta que si hiciera esto para su fábrica de propósito general estaría salteando validaciones CADA vez que creó en esa fábrica. Probablemente sea mejor utilizar esta técnica solo en una subfabricada (o en un rasgo). – tgf

+0

Es casi seguro que quiera poner esto en un rasgo. Vea la respuesta de Tim Scott, a continuación. –

3
foo = build(:foo).tap{ |u| u.save(validate: false) } 
6

Es una mala idea para pasar las validaciones por defecto en fábrica. Se sacará algo de cabello para encontrar eso.

La forma más bonita, pienso:

trait :skip_validate do 
    to_create {|instance| instance.save(validate: false)} 
end 

Luego, en su prueba:

create(:group, :skip_validate, expiry: Time.now + 1.week) 
+0

¡esta es la mejor manera de resolver este problema! –

Cuestiones relacionadas