7

我对 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_date( http://www.railslodge.com/plugins/1160-validates-timeliness ) 的 RSpec 匹配器,这正是我正在寻找的,但据我所知,它已经删除。

我的问题是如何改进我的测试,我是否需要添加尝试最短时间(即毫秒)的测试以确保相应地通过/失败,还是有更好的方法来做到这一点?

提前致谢!

4

2 回答 2

1

尝试这个

validates_date :end_time, :after => [:start_time, Proc.new {1.day.from_now_to_date}]
validates_date :start_time, :after => Time.now
于 2012-11-24T00:33:30.360 回答
1

You could work with valid? and errors.messages:

  • Build anEvent that passes validation except for your start_date and end_date
  • Set the start_date and end_date in the right order, and assert that event.valid? is true
  • Set the start_date and end_date in the wrong order, and assert that it is not valid? and that event.errors.messages includes the right validation errors. (Note, you have to call event.valid? before checking event.errors.messages, otherwise they will be empty)

Example for valid? and 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 #=> {}
于 2012-11-03T04:47:43.423 回答