ruby on rails - rails - Factory-girl crea eso pasa por alto mi modelo de validación
install rspec ubuntu (7)
Dependiendo de su escenario, puede cambiar la validación para que ocurra solo en la actualización. Ejemplo: :validates :expire_date, :presence => true, :on => [:update ]
Estoy usando Factory Girl para crear dos instancias en mi prueba de modelo / unidad para un grupo. Estoy probando el modelo para verificar que una llamada a .current devuelva solo los grupos ''actuales'' de acuerdo con el atributo de expiración como se indica a continuación ...
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 después de 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 forma de crear el Grupo con contundencia o evitar la validación al crear con Factory Girl?
Es una mala idea omitir las validaciones por defecto en fábrica. Se sacará algo de cabello para encontrar eso.
La mejor manera, creo:
trait :skip_validate do
to_create {|instance| instance.save(validate: false)}
end
Luego en tu prueba:
create(:group, :skip_validate, expiry: Time.now + 1.week)
Esto no es muy específico de FactoryGirl, pero siempre puede omitir las validaciones al guardar 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
Para este caso de validación baesd específico de fecha, también podría usar la gema timecop para alterar temporalmente el tiempo para simular el registro anterior que se creó en el pasado.
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) }
EDITAR:
Como se menciona en el hilo de referencia, y por los comentarios / soluciones de otros, es probable que desee ajustar esto en un bloque de características para evitar confusiones / problemas en otras partes de sus pruebas; por ejemplo, cuando estás probando tus validaciones.
Sus fábricas deberían crear objetos válidos por defecto. Descubrí que los atributos transitorios se pueden usar para agregar una lógica condicional como esta:
transient do
skip_validations false
end
before :create do |instance, evaluator|
instance.save(validate: false) if evaluator.skip_validations
end
En tu prueba:
create(:group, skip_validations: true)
foo = build(:foo).tap{ |u| u.save(validate: false) }