質問

私は工場の女の子を使用して、グループのモデル/ユニットテストで2つのインスタンスを作成しています。モデルをテストして、.currentへの呼び出しが、次のように有効期限属性に従って「現在」グループのみを返すことを確認しています...

  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

工場の女の子を使用して作成するときに、グループを強制的に作成したり、検証を回避する方法はありますか?

役に立ちましたか?

解決

これは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) }

編集:

参照されたスレッドで述べたように、および他のコメント/ソリューションによって、テストの他の場所での混乱/問題を避けるために、これを特性ブロックに包むことをお勧めします。たとえば、検証をテストするとき。

工場でデフォルトで検証をスキップするのは悪い考えです。それを見つけて、いくつかの髪が引き出されます。

最も素晴らしい方法だと思います:

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

次に、テストで:

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

この特定のDATE-BAESD検証ケースでは、 タイムコップ 宝石時間を一時的に変更して、過去に作成されている古いレコードをシミュレートします。

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

工場はデフォルトで有効なオブジェクトを作成する必要があります。見つけた 一時的な属性 次のような条件付きロジックを追加するために使用できます。

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)

そのモデルのすべての検証をスキップすることは最善ではありません。

作成 spec/factories/traits.rb ファイル。

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

仕様を修正します

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

シナリオに応じて、更新でのみ検証を変更することができます。例: :validates :expire_date, :presence => true, :on => [:update ]

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top