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

Sar*_*all 7 validation datetime rspec ruby-on-rails 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
Run Code Online (Sandbox Code Playgroud)

在我的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
Run Code Online (Sandbox Code Playgroud)

然而,这并不能真正测试我的开始日期必须在确切的日期时间之前.例如,如果我不小心使用:today而不是:now在我的模型中,这些测试也会通过.

我在网上看到曾经有一个名为validate_date(http://www.railslodge.com/plugins/1160-validates-timeliness)的RSpec匹配器,这正是我正在寻找的,但据我所知,它已被除去.

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

提前致谢!

doe*_*err 1

您可以使用valid?errors.messages

  • 构建一个Event通过验证的程序,除了您start_dateend_date
  • 正确的顺序设置 和start_date,并断言是end_dateevent.valid?true
  • 错误的顺序设置start_date和,并断言它不是并且包含正确的验证错误。(注意,检查前一定要先打电话,否则会为空)end_datevalid?event.errors.messagesevent.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 #=> {}
Run Code Online (Sandbox Code Playgroud)