2011-07-26 53 views
4

有沒有一種方法來正確測試異常提升與隱式主體在rspec?RSpec,隱式主題和例外

例如,失敗:

describe 'test' do 
    subject {raise 'an exception'} 
    it {should raise_exception} 
end 

但這傳遞:

describe 'test' do 
    it "should raise an exception" do 
    lambda{raise 'an exception'}.should raise_exception 
    end 
end 

這是爲什麼?

回答

7

subject接受一個塊,其中返回其餘的主題。

你想要的是這樣的:

describe 'test' do 
    subject { lambda { raise 'an exception' } } 
    it { should raise_exception } 
end 

編輯:澄清評論

此:

describe 'test' do 
    subject { foo } 
    it { should blah_blah_blah } 
end 

(foo).should blah_blah_blah 

或多或少相當於現在,考慮:沒有在lambda,這成爲:

(raise 'an exception').should raise_exception 

看到這裏,當對象被評爲引發異常(之前should被稱爲在所有)。而與拉姆達,就變成:

lambda { raise 'an exception' }.should raise_exception 

在這裏,主題是拉姆達,當should呼叫評估其只計算(在上下文在異常都會被捕獲)。

雖然每次重新評估「主題」,但仍需評估您要調用should的內容。

+0

我想知道爲什麼。主題不被調用和存儲,而是在每個測試中調用。爲什麼我需要用lambda包裝呢? – Mario

+0

因爲「subject」是產生應該調用「should」的東西的塊。通過這樣做,你產生相當於: (拉姆達{提高「例外」})應該raise_exception 而不是像你們會的,上面: (提高「例外」)應該raise_exception 的在調用'should'之前,主體塊將被*評估*(並且,恰巧它會引發異常)。您希望在引發異常的塊上調用「應該」。對不起,如果我不清楚。 –

+0

哎呀,評論格式不太好。澄清更新答案。 –

1

另一個答案很好地解釋瞭解決方案。我只想提到RSpec有一個叫做expect的特殊幫手。這只是更容易閱讀:

# instead of saying: 
lambda { raise 'exception' }.should raise_exception 

# you can say: 
expect { raise 'exception' }.to raise_error 

# a few more examples: 
expect { ... }.to raise_error 
expect { ... }.to raise_error(ErrorClass) 
expect { ... }.to raise_error("message") 
expect { ... }.to raise_error(ErrorClass, "message") 

更多信息可以在RSpec documentation on the built-in matchers中找到。

+0

確實。這位助手在最初的問題和答案時並沒有出現,但這對於尋找這方面信息的人可能會有所幫助。 然而,嚴格來說,這不是對問題的回答。 – Mario