Factory-girl create that bypasses my model validation

后端 未结 9 2152
既然无缘
既然无缘 2021-01-30 06:31

I am using Factory Girl to create two instances in my model/unit test for a Group. I am testing the model to check that a call to .current returns only the \'current\' groups ac

相关标签:
9条回答
  • 2021-01-30 06:40

    Your factories should create valid objects by default. I found that transient attributes can be used to add conditional logic like this:

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

    In your test:

    create(:group, skip_validations: true)
    
    0 讨论(0)
  • 2021-01-30 06:41

    Or you can use both FactoryBot and Timecop with something like:

    trait :expired do
      transient do
        travel_backward_to { 2.days.ago }
      end
      before(:create) do |_instance, evaluator|
        Timecop.travel(evaluator.travel_backward_to)
      end
      after(:create) do
        Timecop.return
      end
    end
    
    let!(:expired_group) { FactoryGirl.create(:group, :expired, travel_backward_to: 5.days.ago, expiry: Time.now - 3.days) }
    

    Edit: Do not update this event after creation or validations will fail.

    0 讨论(0)
  • 2021-01-30 06:43

    This isn't very specific to FactoryGirl, but you can always bypass validations when saving models via 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
    
    0 讨论(0)
  • 2021-01-30 06:43

    Depending on your scenario you could change validation to happen only on update. Example: :validates :expire_date, :presence => true, :on => [:update ]

    0 讨论(0)
  • 2021-01-30 06:44
    foo = build(:foo).tap{ |u| u.save(validate: false) }
    
    0 讨论(0)
  • 2021-01-30 06:45

    It's a bad idea to skip validations by default in factory. Some hair will be pulled out finding that.

    The nicest way, I think:

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

    Then in your test:

    create(:group, :skip_validate, expiry: Time.now + 1.week)
    
    0 讨论(0)
提交回复
热议问题