validates_presence_of rails bot ruby-on-rails ruby-on-rails-3 rspec factory-bot rspec-rails

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) }