2013-02-28 35 views
5

Tôi có validator sau trong mô hình của tôi:RSpec kiểm tra tùy chỉnh validator

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 

Làm thế nào tôi có thể kiểm tra bằng RSpec?

Dưới đây là những gì tôi đã cố gắng cho đến nay: (nhờ 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 

Nhưng tôi nhận được các lỗi sau đây:

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={}> 

Tôi đang làm gì sai? Và làm thế nào tôi có thể đạt được mục tiêu của mình? Bất kỳ trợ giúp hoặc gợi ý nào sẽ được đánh giá cao. Cảm ơn.

Trả lời

11

Vấn đề là bạn đang mong @time_event.errors cư xử như một mảng các chuỗi. Nó không, nó trả về ActiveModel :: lỗi. Như những người khác chỉ ra, bạn cũng cần phải kích hoạt kiểm chứng thực với một cuộc gọi đến 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 
+0

Bạn nói đúng Tôi cần thêm full_messages để nhận lỗi. Tuy nhiên, như người kia đã nói, tôi cần thực sự kiểm tra việc xác nhận hợp lệ với 'hợp lệ? ' – siekfried

+0

Đúng vậy. Tôi đã cập nhật câu trả lời. –

1

Không có lỗi vì bạn chưa gọi sự kiện kích hoạt lỗi. Điều này xảy ra bình thường khi một bản ghi được tạo hoặc lưu. Bạn không thể muốn nhấn cơ sở dữ liệu trong bài kiểm tra của bạn mặc dù và sau đó bạn có thể sử dụng phương pháp valid? như thế này:

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 

cá nhân nhớ sẽ đặt hai bài kiểm tra này vào một từ hợp lệ? được gọi trong trường hợp đầu tiên.

Ngoài ra trẻ vị thành niên: if record.end_time là tốt hơn if !record.end_time.nil?. (Theo ý kiến ​​của tôi ít nhất .... :-))

+0

Bạn nói đúng, nhưng như @Benjamin Sullivan đề xuất, tôi cũng cần thêm full_messages vào lỗi để vượt qua bài kiểm tra. Cảm ơn cũng cho trẻ vị thành niên :) – siekfried

0

Tôi nghĩ rằng bản ghi đã không được xác thực do đó validatior không chạy và không có lỗi nào được áp dụng. Bạn có thể thấy điều này trong đầu ra mã. "Xác nhận: false"

thử:

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 
0

Bạn đã không kiểm tra xác nhận trên thực tế, cộng với tôi sẽ đề nghị bạn thực hiện một spec duy nhất.

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 
1

Giải pháp này làm việc cho tôi (sử dụng Mongoid):

Mô hình

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 

Các thử nghiệm:

it 'is expected to have different states' do 
    expect { create(:oplog, from_status: 'created', to_status: 'created').to raise_error(Mongoid::Errors::Validations) } 
end 

Vì vậy, trong trường hợp của bạn tôi d viết một bài kiểm tra như thế này (nếu sử dụng 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 
Các vấn đề liên quan