测试rails模型使用RSpec验证日期

时间:2012-10-30 11:40:00

标签: ruby-on-rails validation datetime rspec rspec-rails

我对Rails和Rspec有点新意,因此我不确定如何在我的模型中测试日期时间验证是否正确。 我制作了一个具有开始和结束时间的模型事件,并且在这些事件上存在一些重要条件,例如开始时间不能在过去,结束时间必须在开始时间之后。

为了确保这些验证,请使用ValidatesTimeliness https://github.com/adzap/validates_timeliness

我的模型如下:

class Event < ActiveRecord::Base
  ...

  validates_datetime :start_date,
    :after => :now,
    :after_message => "Event cannot start in the past"

  validates_datetime :end_date,
    :after => :start_date,
    :after_message => "End time cannot be before start time"
end

在我的RSpec测试中,我有:

describe Event do
  let(:event) { FactoryGirl.build :event }
  subject { event }

  context "when start_date is before the current time" do
    it {should_not allow_value(1.day.ago).
        for(:start_date)}
  end

  context "when end_date is before or on start date" do
    it {should_not allow_value(event.start_date - 1.day).
        for(:end_date)}

    it {should_not allow_value(event.start_date).
        for(:end_date)}
  end

  context "when the end_date is after the start_date" do
    it {should allow_value(event.start_date + 1.day).
        for(:end_date)}
  end
end

然而,这并没有真正测试我的开始日期必须在确切的日期时间之前。 例如,如果我在模型中意外使用了:today而不是:now,那么这些测试也会通过。

我在网上看到曾经有一个名为validate_datehttp://www.railslodge.com/plugins/1160-validates-timeliness)的RSpec匹配器,这正是我正在寻找的东西,但据我所知,它可以告诉它。已被删除。

我的问题是如何改进我的测试,我是否需要添加尝试最少时间(即ms)的测试以确保相应的通过/失败或者有更好的方法吗?

提前致谢!

2 个答案:

答案 0 :(得分:1)

您可以使用valid?errors.messages

  • 构建一个Event,除了start_dateend_date
  • 之外,它会通过验证
  • 正确顺序设置start_dateend_date,并声明event.valid?true
  • 错误的顺序设置start_dateend_date,并断言它不是valid?event.errors.messages包含正确的验证错误。 (注意,您必须在检查event.valid?之前致电event.errors.messages,否则它们将为空)

valid?errors.messages的示例:

 user = User.new
 user.errors.messages #=> {} # no messages, since validations never ran
 user.valid? # => false
 user.errors.messages #=> {:email=>["can't be blank"]}

 user.email = "foo@bar.com"
 user.valid? #=> true
 user.errors.messages #=> {}

答案 1 :(得分:1)

试试这个

validates_date :end_time, :after => [:start_time, Proc.new {1.day.from_now_to_date}]
validates_date :start_time, :after => Time.now