I have the following validator in my model:
class ContinuumValidator < ActiveModel::Validator
def validate(record)
if !record.end_time.nil? and record.end_time < record.start_time
record.errors[:base] << "An event can not be finished if it did not start yet..."
end
end
end
class Hrm::TimeEvent < ActiveRecord::Base
validates_with ContinuumValidator
end
How can I test it using Rspec?
Here is what I have tried so far: (thanks to zetetic )
describe "validation error" do
before do
@time_event = Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2)
end
it "should not be valid if end time is lower than start time" do
@time_event.should_not be_valid
end
it "raises an error if end time is lower than start time" do
@time_event.errors.should include("An event can not be finished if it did not start yet...")
end
end
But I get the following errors:
1) Hrm::TimeEvent validation error raises an error if end time is lower than start time
Failure/Error: @time_event.errors.should include("An event can not be finished if it did not start yet...")
expected #<ActiveModel::Errors:0x007fd1d8e02c50 @base=#<Hrm::TimeEvent id: nil, start_time: "2012-10-05 08:00:00", end_time: "2012-10-05 07:00:00", event_type: 2, employee_id: nil, created_at: nil, updated_at: nil, not_punched: false, validated: false, replace_id: nil>, @messages={}> to include "An event can not be finished if it did not start yet..."
Diff:
@@ -1,2 +1,5 @@
-["An event can not be finished if it did not start yet..."]
+#<ActiveModel::Errors:0x007fd1d8e02c50
+ @base=
+ #<Hrm::TimeEvent id: nil, start_time: "2012-10-05 08:00:00", end_time: "2012-10-05 07:00:00", event_type: 2, employee_id: nil, created_at: nil, updated_at: nil, not_punched: false, validated: false, replace_id: nil>,
+ @messages={}>
What am I doing wrong? And how can I achieve my goal? Any help or suggestion would be appreciated. Thanks.
The problem is that you're expecting @time_event.errors
to behave like an array of strings. It doesn't, it returns ActiveModel::Errors. As others pointed out, you also need to trigger the validations with a call to valid?
:
it "raises an error if end time is lower than start time" do
@time_event.valid?
@time_event.errors.full_messages.should include("An event can not be finished if it did not start yet...")
end
There are no errors because you haven't called an event that triggers the errors. This happens normally when a record is created or saved. You may not want to hit the database in your test though and then you can use the method valid?
like this:
it "raises an error if end time is lower than start time" do
@time_event.valid?
@time_event.errors.should include("An event can not be finished if it did not start yet...")
end
Me personally would put these two tests into one since valid? is called in the first case.
Also a minor: if record.end_time
is better than if !record.end_time.nil?
. (In my opinion at least.... :-) )
This solution works for me (using Mongoid):
The model
class OpLog
...
field :from_status, type: String
field :to_status, type: String
...
validate :states_must_differ
def states_must_differ
if self.from_status == self.to_status
errors.add(:from_status, "must differ from 'to_status'")
errors.add(:to_status, "must differ from 'from_status'")
end
end
...
end
The test:
it 'is expected to have different states' do
expect { create(:oplog, from_status: 'created', to_status: 'created').to raise_error(Mongoid::Errors::Validations) }
end
So in your case I'd write a test like this (if using ActiveRecord):
it 'raises an error if end time is lower than start time' do
expect { create(Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2)) }.to raise_error(ActiveRecord::Errors)
end
I think the record wasnt validated therefore the validatior didn't run and no error was aded. You can see this in the code output. "validated: false"
try:
it "raises an error if end time is lower than start time" do
@time_event.valid?
@time_event.errors.should include("An event can not be finished if it did not start yet...")
end
You have not tested the validation actually, plus i would suggest you to make a single spec.
describe "validation error" do
before { @time_event = Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2) }
it "raises an error if end time is lower than start time" do
@time_event.valid?
@time_event.errors.should include("An event can not be finished if it did not start yet...")
end
end
class ContinuumValidator < ActiveModel::Validator
def validate(record)
if record.end_time and record.end_time < record.start_time
record.error.add_to_base << "An event can not be finished if it did not start yet..."
end
end
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.