2011-09-15 24 views
2

我有一個rspec測試,我期望失敗,但它通過,因爲它正在測試的代碼挽救rspec引發的異常。這裏的情況爲例:Rspec誤報,因爲失敗異常在被測試的代碼中得到挽救

class Thing do 

    def self.method_being_tested(object) 
    # ... do some stuff 

    begin 
     object.save! 
    rescue Exception => e 
     # Swallow the exception and log it 
    end 
    end 

end 

在RSpec的文件:「object.save」

describe "method_being_tested" do 
    it "should not call 'save!' on the object passed in" do 
    # ... set up the test conditions 

    mock_object.should_not_receive(:save!) 
    Thing.method_being_tested(mock_object) 
    end 
end 

我知道,執行是到達被測試的方法的線,因此測試應該失敗,但測試通過。使用救援塊中的調試器,我發現以下幾點:

(rdb:1) p e # print the exception object "e" 
#<RSpec::Mocks::MockExpectationError: (Mock "TestObject_1001").save! 
    expected: 0 times 
    received: 1 time> 

所以基本上測試失敗了,但是,但故障是由非常代碼它試圖測試抑制。我找不到一種可行的方法來阻止這些代碼吞噬Rspec異常,而不會影響代碼。我不希望代碼明確檢查異常是否是Rspec異常,因爲這是不好的設計(應該爲代碼編寫測試,代碼不應該寫入測試)。但是我也無法檢查這個異常是否是我想讓它捕捉的特定類型,因爲我希望它抓住任何可以在正常生產環境中引發的任何類型。

有人在我面前肯定有這個問題!請幫我找一個解決方案。

+0

你問是否有辦法捕捉所有異常,除了一種你不想捕捉的東西,而不檢查它在捕捉代碼中的異常類型。這裏的答案是否定的。 –

回答

1

從rspec的-模擬:

module RSpec 
    module Mocks 
    class MockExpectationError < Exception 
    end 

    class AmbiguousReturnError < StandardError 
    end 
    end 
end 

你真的需要捕捉Exception?你能不能趕上StandardError

捕獲所有異常通常是一件壞事。如果你想忽略保存拋出的異常

class Thing do 

    def self.method_being_tested!(object) 

    # ... do some stuff 

    return object.save 
    end 

end 

+0

這很有幫助。謝謝。 –

+0

@zetetic可以說,捕捉和忽略異常是一件壞事。捕捉任何(或全部)例外並對其採取行動可能是完全合法的。 –

1

我會重構它就像這樣!調用保存沒有意義!首先。您只需調用save並相應地通知調用代碼。

+0

我不確定這是否是一般解決方案,如果保存!而是一個API調用,但仍然存在處理異常的問題 – xxjjnn

3

假設代碼是正確的,是:

describe "method_being_tested" do 
    it "should not call 'save!' on the object passed in" do 
    # ... set up the test conditions 
    calls = 0 
    mock_object.stub(:save!) { calls += 1 } 
    expect {Thing.method_being_tested(mock_object)}.to_not change{calls} 
    end 
end 

如果沒有必要(來自@維託 - 波塔輸入)趕絕所有的異常,包括SystemExitNoMemoryErrorSignalException等:

begin 
    object.save! 
rescue StandardError => e 
    # Swallow "normal" exceptions and log it 
end 

StandardError是由rescue捕獲的默認異常級別。