2013-05-31 33 views
21

Tôi có một phương pháp mà thực hiện một số hành động trên mô hình Cát và trong trường hợp nhập sai đặt ra một ngoại lệ:Làm cách nào để tôi mong đợi điều gì đó làm tăng ngoại lệ trong RSpec?

context "hungry cat" do 
    it { expect { eat(what: nil) }.to raise_error } 
end 

Những gì tôi muốn làm là để kiểm tra xem tình trạng mèo thay đổi phương pháp này, như thế:

context "hungry cat" do 
    it { expect { eat(what: nil) }.to raise_error } 
    it { expect { eat(what: nil) }.not_to change(cat, :status) } 
end 

Vấn đề là vì eat(what: nil) sẽ tăng ngoại lệ thứ hai it sẽ không thành công bất kể điều gì. Vì vậy, nó có thể bỏ qua ngoại lệ và kiểm tra một số điều kiện?

Tôi biết rằng nó có thể làm điều gì đó như:

it do 
    expect do 
    begin 
     eat(what: nil) 
    rescue 
    end 
    end.not_to change(cat, :status) 
end 

Nhưng đó là cách quá xấu xí.

+2

Làm thế nào về 'nó {mong đợi {ăn (what: nil) rescue nil} .not_to change (cat,: status)}'? – awendt

+0

@awendt tốt nhất, bạn có thể đăng nó làm câu trả lời không? – Andrew

+0

Trong 'Test/Unit', có một khẳng định tốt đẹp,' assert_raise', tôi nghĩ vậy. –

Trả lời

18

Bạn có thể sử dụng "giải cứu nil" thành ngữ để rút ngắn những gì bạn đã có:

it { expect { eat(what: nil) rescue nil }.not_to change(cat, :status) } 
+4

Công trình này, nhưng tôi muốn có một cách làm rspec này, ví dụ: 'expect {...} .ignoring_errors.to change (cat,: status) ' –

0

Nghe có vẻ lạ khi mã eat(what: nil) không chạy riêng biệt cho mỗi thử nghiệm của bạn và đang ảnh hưởng đến các thử nghiệm khác. Tôi không chắc chắn, nhưng có lẽ viết lại các bài kiểm tra hơi sẽ giải quyết vấn đề hoặc xác định chính xác hơn nơi mà vấn đề là (chọn hương vị của bạn dưới đây).

Sử dụng should:

context "hungry cat" do 
    context "when not given anything to eat" do 
    subject { -> { eat(what: nil) } } 
    it { should raise_error } 
    it { should_not change(cat, :status) } 
    end 
end 

Sử dụng expect:

context "hungry cat" do 
    context "when not given anything to eat" do 
    let(:eating_nothing) { -> { eat(what: nil) } } 
    it "raises an error" do 
     expect(eating_nothing).to raise_error 
    end 
    it "doesn't change cat's status" do 
     expect(eating_nothing).to_not change(cat, :status) 
    end 
    end 
end 
+0

Tôi nghĩ rằng bạn hiểu nhầm câu hỏi. Nếu 'eat' đặt ra một ngoại lệ, trường hợp thứ hai sẽ luôn thất bại vì ngoại lệ không được giải quyết. – Andrew

+0

Có lẽ tôi đã làm. Hành vi mong đợi trong hệ thống của bạn có ngoại lệ không được giải quyết mà người dùng của bạn có thể tạo ra không? Nếu vậy, bạn có thể giải thích lý do tại sao, hoặc ở đây hoặc trong một chỉnh sửa cho câu hỏi của bạn? –

+0

Vâng, đó là tất nhiên hành vi mong đợi, hơn nữa hầu hết các thư viện ruby ​​có thể tạo ra các ngoại lệ cần được xử lý bởi người dùng của họ và hành vi này cũng nên được kiểm tra. Ví dụ. đường ray '#save!', 'Float ('aaa')', EOFError trong 'File # read'. Những gì tôi muốn thử nghiệm trong trường hợp của tôi là bối cảnh đã được khôi phục thành công sau khi ngoại lệ đã được ném (giao dịch cuộn lại, mô tả đóng cửa, vv). – Andrew

12

Trong RSpec 3 bạn có thể chuỗi hai bài kiểm tra thành một. Tôi thấy điều này dễ đọc hơn phương pháp rescue nil.

it { expect { eat(what: nil) }.to raise_error.and not_to change(cat, :status)}

+4

Bạn có chắc đây là cú pháp đúng không? Nó cho tôi lỗi: 'NoMethodError: phương thức undefined 'not_to' cho # dombesz

+1

Không có điều này sẽ không hoạt động, xem bình luận của tôi dưới đây. –

11

Bạn có thể chain khẳng định dương tính với and. Nếu bạn muốn trộn lẫn trong một chuỗi bị phủ nhận trong chuỗi, RSpec 3.1 đã giới thiệu define_negated_matcher.

Bạn có thể làm một cái gì đó như:

RSpec::Matchers.define_negated_matcher :avoid_changing, :change 

expect { eat(what: nil) } 
    .to raise_error 
    .and avoid_changing(cat, :status) 

Lấy cảm hứng từ this comment.

+1

Điều này thực sự tuyệt vời cảm ơn bạn. Không thể tin rằng tôi đã không chạy vào điều này trước đây. – adaam

+1

Đây sẽ là câu trả lời hay! –

Các vấn đề liên quan