Ruby-on-rails RSpec:如何测试方法是否被调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21262309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RSpec: how to test if a method was called?
提问by Mikey Hogarth
When writing RSpec tests, I find myself writing a lot of code that looks like this in order to ensure that a method was called during the execution of a test (for the sake of argument, let's just say I can't really interrogate the state of the object after the call because the operation the method performs is not easy to see the effect of).
在编写 RSpec 测试时,我发现自己编写了很多看起来像这样的代码,以确保在测试执行期间调用了一个方法(为了论证,假设我不能真正询问状态调用后的对象,因为方法执行的操作不容易看到效果)。
describe "#foo"
it "should call 'bar' with appropriate arguments" do
called_bar = false
subject.stub(:bar).with("an argument I want") { called_bar = true }
subject.foo
expect(called_bar).to be_true
end
end
What I want to know is: Is there a nicer syntax available than this? Am I missing some funky RSpec awesomeness that would reduce the above code down to a few lines? should_receivesounds like it should do this but reading further it sounds like that's not exactly what it does.
我想知道的是:有没有比这更好的语法?我是否错过了一些时髦的 RSpec 很棒的东西,可以将上面的代码减少到几行?should_receive听起来它应该这样做,但进一步阅读它听起来不像它所做的那样。
回答by wacko
it "should call 'bar' with appropriate arguments" do
expect(subject).to receive(:bar).with("an argument I want")
subject.foo
end
回答by Uri Agassi
In the new rspecexpectsyntaxthis would be:
在新rspecexpect语法中,这将是:
expect(subject).to receive(:bar).with("an argument I want")
回答by bjhaid
The below should work
下面应该工作
describe "#foo"
it "should call 'bar' with appropriate arguments" do
subject.stub(:bar)
subject.foo
expect(subject).to have_received(:bar).with("Invalid number of arguments")
end
end
Documentation: https://github.com/rspec/rspec-mocks#expecting-arguments
文档:https: //github.com/rspec/rspec-mocks#expecting-arguments
回答by Yi Zeng
To fully comply with RSpec ~> 3.1 syntax and rubocop-rspec's default option for rule RSpec/MessageSpies, here's what you can do with spy:
要完全遵守 RSpec ~> 3.1 语法和rubocop-rspecrule 的默认选项RSpec/MessageSpies,您可以使用以下方法spy:
Message expectations put an example's expectation at the start, before you've invoked the code-under-test. Many developers prefer using an arrange-act-assert (or given-when-then) pattern for structuring tests. Spies are an alternate type of test double that support this pattern by allowing you to expect that a message has been received after the fact, using have_received.
在您调用被测代码之前,消息期望将示例的期望放在开头。许多开发人员更喜欢使用安排-行为-断言(或给定-何时-然后)模式来构建测试。间谍是另一种类型的测试替身,它支持这种模式,它允许您使用 have_received 预期在事后已收到消息。
# arrange.
invitation = spy('invitation')
# act.
invitation.deliver("[email protected]")
# assert.
expect(invitation).to have_received(:deliver).with("[email protected]")
If you don't use rubocop-rspec or using non-default option. You may, of course, use RSpec 3 default with expect.
如果您不使用 rubocop-rspec 或使用非默认选项。当然,您可以使用带有期望的 RSpec 3 默认值。
dbl = double("Some Collaborator")
expect(dbl).to receive(:foo).with("[email protected]")
- Official Documentation: https://relishapp.com/rspec/rspec-mocks/docs/basics/spies
- rubocop-rspec: https://docs.rubocop.org/projects/rspec/en/latest/cops_rspec/#rspecmessagespies

