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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 23:15:12  来源:igfitidea点击:

RSpec: how to test if a method was called?

ruby-on-railsrubyrspec

提问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]")