2016-03-23 29 views
1

rspec-mocks'expect(target).to receive(:message).with(arg_matcher)只會在測試結束時顯示錯誤,如果目標是通過參數不匹配傳遞給with的arg匹配器來調用的。有沒有辦法強制它失敗 - 即一旦目標被調用不匹配的參數? RR以這種方式工作。如何使rspec-mocks期待receive.with熱切失敗

我正面臨的問題是,當我使用上面的arg_matcher設置了這個模擬器時,測試開始失敗,因爲目標被不同的參數調用,但是在測試結束之前另一個斷言失敗了,所以我只能從這個斷言中看到錯誤,而不是從缺少的模擬中(這會顯示出預期的參數和實際調用的參數之間的差異)。

使用rspec-mocks 3.3.2。

回答

2

我不知道如何使receive失敗。然而,have_received急切失敗,所以如果它是幾個期望中的第一個,那麼它將是未通過測試並且RSpec報告的那個。

class Foo 
    def self.bar(baz) 
    end 
end 

describe "RSpec" do 
    it "reports a non-mock expectation failure before a mock expectation failure" do 
    expect(Foo).to receive(:bar).with(1) 
    expect(true).to be_falsy # RSpec reports this failure 
    Foo.bar 2 
    end 

    it "reports a spy expectation failure when you'd expect it to be reported" do 
    allow(Foo).to receive(:bar) # Spy on Foo 
    Foo.bar 2 
    expect(Foo).to have_received(:bar).with(1) # RSpec reports this failure 
    expect(true).to be_falsy 
    end 

end 

查看the documentation of RSpec spies瞭解詳情。

這種解決方案可能是最好的,如果

  • ,如果你喜歡你的測試在邏輯arrange-act-assert序列像我這樣做
  • 如果間諜期望失敗,你不關心其他期望
  • 如果你介意allow設置的間諜小於你的額外打字 block

Regular mock S和阿達什訥的解決方案是更好的

  • 你想看到的兩個預期結果無論要麼失敗
  • ,如果你不介意的aggregate_failures塊不到你介意樹立間諜allow的額外的輸入
1

測試啓動失敗,因爲目標是調用不同的參數,可以,但接着又斷言測試結束之前失敗,所以我只看到錯誤的這種說法,而不是從失蹤模擬

如果我正確閱讀這個內容,你在一個規範中有多個expect斷言,第一個失敗,所以你沒有看到第二個/第三個斷言失敗?

如果是的話,我會考慮使用RSpec's aggregate_failures introduced in v3.3,其中收集的失敗,但隨後的運行斷言:

aggregate_failures("verifying response") do 
    expect(response.status).to eq(200) 
    expect(response.headers).to include("Content-Type" => "text/plain") 
    expect(response.body).to include("Success") 
end 

# Which gives you nice errors for all assertions 

1) Client returns a successful response 
    Got 3 failures: 

    1.1) Got 3 failures from failure aggregation block "testing response". 
      # ./spec/use_block_form_spec.rb:18 
      # ./spec/use_block_form_spec.rb:10 

      1.1.1) Failure/Error: expect(response.status).to eq(200) 

        expected: 200 
         got: 404 

        (compared using ==) 
       # ./spec/use_block_form_spec.rb:19 

      1.1.2) Failure/Error: expect(response.headers).to include("Content-Type" => "application/json") 
        expected {"Content-Type" => "text/plain"} to include {"Content-Type" => "application/json"} 
        Diff: 
        @@ -1,2 +1,2 @@ 
        -[{"Content-Type"=>"application/json"}] 
        +"Content-Type" => "text/plain", 
       # ./spec/use_block_form_spec.rb:20 

      1.1.3) Failure/Error: expect(response.body).to eq('{"message":"Success"}') 

        expected: "{\"message\":\"Success\"}" 
         got: "Not Found" 

        (compared using ==) 
       # ./spec/use_block_form_spec.rb:21 

    1.2) Failure/Error: expect(false).to be(true), "after hook failure" 
      after hook failure 
      # ./spec/use_block_form_spec.rb:6 
      # ./spec/use_block_form_spec.rb:10 

    1.3) Failure/Error: expect(false).to be(true), "around hook failure" 
      around hook failure 
      # ./spec/use_block_form_spec.rb:12 

您還可以標記一個描述塊aggregate_failures

RSpec.describe ClassName, :aggregate_failures do 
    # stuff 
end 
+0

這是很棒的信息,謝謝!但我的問題不同 - @Dave Schweisguth說得對。 – astgtciv

+1

Adarsh沒有完全重申你的問題,但是'aggregate_failures'的確解決了它:如果你將整個測試包裝在'aggregate_failures'中,你會看到非模擬失敗和模擬失敗。 (正如我上面所說的,你是否希望看到非模擬失敗取決於你正在測試的內容。) –