【问题标题】:FactoryGirl Rspec creating invalid instancesFactoryGirl Rspec 创建无效实例
【发布时间】:2014-07-11 19:23:15
【问题描述】:

所以我有一个围绕日历上的事件展开的应用程序。事件有一个starts_at 和ends_at。添加了一项新要求,以限制仅在未来创建新事件,更具体地说 >= 今天午夜。所以很自然地,我修改了我的 validate 方法以在实例化时检查这一点。然而,这在使用 FactoryGirl 对 RSpec 进行测试时会产生问题。

许多测试都需要检查过去事件的某些要求。问题是,我不能再在过去创建这些元素,因为它没有通过我的验证。所以我找到了一些方法来解决这个问题

allow(instance)to receive(:starts_at).and_return(some_future_time)

expect_any_instance_of(Event).to receive(:check_valid_times).and_return(true)

这是应用程序中的一些简单代码

#Model
class Event < ActiveRecord::Base
  validate :check_for_valid_times

  private:
    def check_for_valid_times
      if starts_at.present? && (starts_at < Time.now.at_beginning_of_day)
        errors.add(:base, I18n.t('event.start_time_before_now'))
      end
      unless starts_at.present? && (starts_at < ends_at)
        errors.add(:base, I18n.t('event.end_time_before_start'))'
      end
    end
end

我的工厂

#factory
require 'factory_girl'

FactoryGirl.define do
  factory :event do
    starts_at { 2.hour.from_now.to_s }
  end
end

问题:有没有一种干净的方法可以做到这一点,而不必去处理每个事件的创建并在我的所有测试中专门处理它们?目前,我不得不以不同的方式处理其中的一些问题。

如果我应该发布代码的其他部分,请告诉我。

一如既往,提前感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails ruby validation rspec factory-bot


    【解决方案1】:

    我通常解决此类问题的方法是timecop gem。

    例如:

    Timecop.freeze 1.hour.ago do
      create(:event)
    end
    

    然后,您可以将它们放在 let 块中,或者放在 spec/support/events.rb 的助手中,以保持其干燥和可维护。

    使用 timecop,您实际上可以完全模拟测试。因此,在您关心的过去时间正确创建事件,然后将时间恢复正常并查看您的测试显示该事件是过去的并且无法更改,等等。它允许完整、准确和可理解的时间敏感测试。 RSpec 助手、共享上下文和 before/let 块可以处理保持测试干净。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      相关资源
      最近更新 更多