简体   繁体   English

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

[英]Testing that rails model validates date with RSpec

I'm a bit new to Rails and Rspec and as such I'm not sure how to test that date time validations are correct in my model. 我对Rails和Rspec有点新意,因此我不确定如何在我的模型中测试日期时间验证是否正确。 I've made a model Event that has start and end times and there's a few imporant conditions on these such as a start time cannot be in the past and the end time must be after the start time. 我做了一个有开始和结束时间的模型事件,并且在这些事件上有一些重要条件,例如开始时间不能在过去,结束时间必须在开始时间之后。

To ensure these validations I'm using ValidatesTimeliness https://github.com/adzap/validates_timeliness 为了确保这些验证我正在使用ValidatesTimeliness https://github.com/adzap/validates_timeliness

My model is as follows: 我的模型如下:

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

In my RSpec test I have: 在我的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

However this doesn't really test that my start date had to be before the exact date time. 然而,这并不能真正测试我的开始日期必须在确切的日期时间之前。 For example if I'd accidentally used :today instead of :now in my model, these tests would also pass. 例如,如果我不小心使用了:today而不是:now在我的模型中,这些测试也会通过。

I read online that there used to be an RSpec matcher called validate_date ( http://www.railslodge.com/plugins/1160-validates-timeliness ) which would be exactly what I'm looking for but as far as I can tell it's been removed. 我在网上看到曾经有一个名为validate_date的RSpec匹配器( http://www.railslodge.com/plugins/1160-validates-timeliness ),这正是我正在寻找的,但据我所知,它是被删除了。

My question is how can I improve my tests, do I need to add tests that try the smallest amount of time (ie a ms) to ensure the pass/fail accordingly or is there a better way to do it? 我的问题是如何改进我的测试,我是否需要添加尝试最少时间(即ms)的测试以确保相应的通过/失败,或者是否有更好的方法来做到这一点?

Thanks in advance! 提前致谢!

You could work with valid? 你可以valid? and errors.messages : errors.messages

  • Build an Event that passes validation except for your start_date and end_date 构建一个通过验证的Event ,除了你的start_dateend_date
  • Set the start_date and end_date in the right order, and assert that event.valid? 正确的顺序设置start_dateend_date ,并断言event.valid? is true true
  • Set the start_date and end_date in the wrong order, and assert that it is not valid? 错误的顺序设置start_dateend_date ,并断言它valid? and that event.errors.messages includes the right validation errors. 并且event.errors.messages包含正确的验证错误。 (Note, you have to call event.valid? before checking event.errors.messages , otherwise they will be empty) (注意,你必须在检查event.errors.messages之前调用event.valid?否则它们将为空)

Example for valid? valid?例子valid? and errors.messages : 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 #=> {}

Try this 尝试这个

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM