目前(rspec-mocks 2.10.1)没有等效于unstub
但 for的方法should_receive
。您可以使用 重置所有存根和模拟rspec_reset
,还可以编写肮脏的技巧来消除特定的期望(我不推荐)。
以下是删除对象上所有存根和期望的示例:
describe "resetting stubs and expectations with rspec_reset" do
before do
@person = mock('person')
@person.should_receive(:poke)
end
it "should not fail when we reset all stubs and expectations" do
@person.rspec_reset
end
end
请注意,此方法在 rspec 源代码中注释为@private
,这意味着您应该避免使用它而不是绝对必要的,并且它可能会在 rspec 的未来版本中中断而不会发出警告。然而,它在 rspec 本身的规范中被广泛使用,因此它似乎不太可能很快被弃用。
在深入研究 rspec-mocks 代码之后,您当然可以做一些非常讨厌的事情并自己撕掉一个特定的期望:
# Works in rspec 2.10.1
describe "removing an expectation with an ugly hack" do
before do
@person = mock('person')
@person.should_receive(:poke)
end
it "should not fail after we hack rspec by violating every law of good programming, ever" do
@person.instance_variable_get(:@mock_proxy).instance_variable_get(:@method_double)[:poke].clear
end
end
这真的很糟糕,因为它违反了 rspec 测试包的封装,你不应该这样做。相反,如果您确实有一个令人信服的理由来消除特定的期望,那么正确的做法是在 rspec-mocks 的上游添加一个公共方法,该方法添加一个并行方法,unstub
但用于消除特定的期望。它可能位于此处(请注意此文件中的stub
and的定义unstub
):
https://github.com/rspec/rspec-mocks/blob/master/lib/rspec/mocks/methods.rb
在使用上述任何建议来消除期望之前,您可能需要考虑您的规范是否真的需要这样做,或者是否应该重构它们。Usingshould_receive
是关于您的代码的断言,通常您应该尝试创建it
只断言一件事的示例(即块)。我会很好奇为什么你需要类似的东西,rspec_reset
除非你试图在全局设置中做太多事情(例如before :each
或之前 :all 块),或者你的例子试图做太多事情(即使用多个断言在一个例子中)。
一个例外当然可能是在 rspec-mocks 的测试套件中,rspec_reset
它用于在测试应用存根和模拟的功能的示例之间重置状态。除非您这样做,否则您的测试可能会得到改进,以不依赖于对象上存根和模拟的全局重置。
我希望这会有所帮助,如果您认为有一个合法的案例可以添加一个等效的方法,unstub
但对于消息期望(即,在使用之后should_receive
),我希望这会有所帮助。如果我确信这是一件可以做的事情,我会考虑添加此方法并建议将其添加到上游。也许它会被称为unset_expectation
?也请随意使用上述代码和内部结构中的指南,自行组合 rspec-mocks 的拉取请求,我们将看看它是否被接受以创建等效于unstub
.