Pregunta

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 devuelve solo los grupos 'actuales' de acuerdo con el atributo de vencimiento según lo siguiente ...

  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 validación en el modelo que verifica el vencimiento de un nuevo grupo es 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 manera de crear con fuerza el grupo o evitar la validación al crear Usar Factory Girl?

¿Fue útil?

Solución

Esto no es muy específico para FactoryGirl, pero siempre puede evitar 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

Otros consejos

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 referenciado, y por los comentarios/soluciones de otros, es probable que desee envolver esto en un bloque de rasgos para evitar confusiones/problemas en otras partes de sus pruebas; Por ejemplo, cuando está probando sus validaciones.

Es una mala idea omitir validaciones por defecto en fábrica. Se sacará un cabello al encontrar eso.

La forma más bonita, 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)

Para este caso específico de validación de fecha de fecha, también puede usar el punto de vista GEM para alterar temporalmente el tiempo para simular el antiguo registro que se crea en el pasado.

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

Sus fábricas deben crear objetos válidos de forma predeterminada. encontre eso atributos transitorios se puede usar para agregar 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)

No es mejor omitir toda la validación de ese modelo.

crear spec/factories/traits.rb expediente.

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

arreglar especificaciones

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

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

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 ]

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top