Заводская девушка создает, что обходит мою модель проверки


Я использую Factory Girl для создания двух экземпляров в моей модели / модульном тесте для группы. Я тестирую модель, чтобы проверить, что вызов .current возвращает только группы "current" в соответствии с атрибутом expiry, как показано ниже...

  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

моя проблема заключается в том, что у меня есть проверка в модели, которая проверяет срок действия новой группы после сегодняшней даты. Это вызывает сбой проверки ниже.

  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

есть ли способ принудительно создать группу или получить вокруг проверки при создании с помощью Factory Girl?

7 55

7 ответов:

это не очень специфично для FactoryGirl, но вы всегда можете обойти проверки при сохранении моделей через 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

Я предпочитаю это решение от https://github.com/thoughtbot/factory_girl/issues/578.

внутри завода:

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

EDIT:

Как уже упоминалось в ссылочном потоке, и другими комментариями/решениями, вы, вероятно, захотите обернуть это в блок признаков, чтобы избежать путаницы/проблем в других местах ваших тестов; например, когда вы тестируете свои проверки.

Это плохая идея, чтобы пропустить проверки по умолчанию на заводе. Некоторые волосы будут вырваны, обнаружив это.

самый приятный способ, я думаю:

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

тогда в вашем тесте:

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

для этого конкретного случая проверки даты-baesd вы также можете использовать timecop драгоценный камень, чтобы временно изменить время, чтобы имитировать старую запись, созданную в прошлом.

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

в зависимости от вашего сценария вы можете изменить проверку, чтобы она происходила только при обновлении. Пример: :validates :expire_date, :presence => true, :on => [:update ]

ваши фабрики должны создавать допустимые объекты по умолчанию. Я нашел это преходящие атрибуты можно использовать для добавления условной логики следующим образом:

transient do
  skip_validations false
end

before :create do |instance, evaluator|
  instance.save(validate: false) if evaluator.skip_validations
end

в вашем тесте:

create(:group, skip_validations: true)