2012-03-12 202 views
1

我正在使用rspec和rspec mocks庫進行存根/嘲弄,但我開始認爲將方法和斷言如何使用的方法之間的界限模糊不清。在我的測試中,我會經常寫這樣的:從rspec中斷言斷言與斷言

before(:each) do 
    subject.should_receive(:sum).once.with([1, 2, 3]).and_return(6) 
end 

it("should do something that relies on sum") do 
    subject.call_something([1, 2, 3]).should == 24 
end 

但是我的斷言是什麼?這call_something([1, 2, 3])

  • 返回24
  • 呼叫sum([1, 2, 3])這期間的執行

但是,只有一個it塊 - 其他斷言存根定義隱藏起來。換句話說,我的存根也是我的斷言。那豈不是更清晰的將二者分開,並把一個明確的說法在如何廢止方法被調用:

before(:each) do 
    # set up what my stub should return for a given input 
    subject.may_receive(:sum).with([1, 2, 3]).and_return(6) 
end 

# assert how my stub was actually called 
it("should have called sum with 1, 2, 3") do 
    # this is pseudo-rspec 
    subject.call_something([1, 2, 3]).should have_called(:sum).on(subject).once.with([1, 2, 3]) 
end 
it("should do something that relies on sum") do 
    subject.call_something([1, 2, 3]).should == 24 
end 

這種方式是很清楚,我斷言,因爲我的存根定義和說法有被分開。我可以在頂部設置我的測試,然後檢查底部的行爲,而不是混合兩者。

所以,我的問題是有沒有辦法做到這一點?大多數模擬框架的工作方式與rspec-mocks相同,並定義瞭如何使用存根方法以及預期行爲的契約,然後自動檢查最後的斷言。

我的觀點是關於BDD如何工作的概念,可能有點微妙。讓我知道我需要進一步澄清!

回答

2

你是對的。 should_receive斷言(更準確地說它是期望)並且不應該在before塊中進行。如果你需要的should_receive的磕碰副作用,那麼在你的before分別存根:

before do 
    subject.stub(:sum).and_return(6) 
end 

it "should do something that relies on sum" do 
    subject.should_receive(:sum).once.with([1, 2, 3]).and_return(6) 
    subject.call_something([1, 2, 3]).should == 24 
end 

這使磕碰和期待獨立和屬於他們的地方。

+0

這看起來不錯。但是如果我需要多次調用'sum'並用不同的參數並且每次都得到不同的結果呢? (這就是爲什麼我傳統上避免使用存根) – iainbeeston 2012-03-13 03:23:44

+0

如果'stub'的返回值發生變化,那麼測試應該可能位於不同的'context'塊中,在這種情況下,您可以使用'let's來減少重複'之前'塊。 – 2012-03-13 03:26:19