RSpec:如何测试一个方法是不是被调用?
Posted
技术标签:
【中文标题】RSpec:如何测试一个方法是不是被调用?【英文标题】:RSpec: how to test if a method was called?RSpec:如何测试一个方法是否被调用? 【发布时间】:2014-02-11 07:03:04 【问题描述】:在编写 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
我想知道的是:有没有比这更好的语法?我是否错过了一些将上述代码减少到几行的时髦的 RSpec 很棒的东西? should_receive
听起来它应该这样做,但进一步阅读它听起来并不完全是它的作用。
【问题讨论】:
查看这里:***.com/questions/1328277/… @Peter Alfvin OP 在should_receive
上询问语法,所以我认为这个问题会有所帮助。
【参考方案1】:
it "should call 'bar' with appropriate arguments" do
expect(subject).to receive(:bar).with("an argument I want")
subject.foo
end
【讨论】:
抱歉,我不明白在这个例子中这种“to ..receive(:bar)”的格式是如何检查“called_bar”的值的。你能给我解释一下吗? @ecoding5 没有。它不会也不应该检查called_bar
。这只是一个确保调用该方法的标志,但是使用expect(...).to receive(...)
,您已经涵盖了这一点。它更加清晰和语义化
@wacko 哦,明白了,感谢您的清理。我第一次没抓到。【参考方案2】:
在新的rspec
expect
syntax 中,这将是:
expect(subject).to receive(:bar).with("an argument I want")
【讨论】:
【参考方案3】:以下应该可以工作
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
文档:https://github.com/rspec/rspec-mocks#expecting-arguments
【讨论】:
谢谢 - 我收到了“NoMethodError”has_received? - 认为这可能与 rspec versoins 有关。我找到了另一种对我有用的解决方案(上面标记为正确的那个) @MikeyHogarth 这个答案是建议have_received
(事后“间谍”方法),而不是has_received
,它不属于我所知道的任何版本的RSpec。【参考方案4】:
为了完全符合 RSpec ~> 3.1 语法和 rubocop-rspec
规则 RSpec/MessageSpies
的默认选项,您可以使用 spy
执行以下操作:
消息期望将示例的期望放在开头,在您调用 被测代码。许多开发人员更喜欢使用arrange-act-assert(或given-when-then) 结构化测试的模式。间谍是支持这一点的另一种测试替身 通过允许您期望在事后收到消息的模式,使用 have_received。
# arrange.
invitation = spy('invitation')
# act.
invitation.deliver("foo@example.com")
# assert.
expect(invitation).to have_received(:deliver).with("foo@example.com")
如果您不使用 rubocop-rspec 或使用非默认选项。当然,您可以将 RSpec 3 默认值与 expect 一起使用。
dbl = double("Some Collaborator")
expect(dbl).to receive(:foo).with("foo@example.com")
官方文档:https://relishapp.com/rspec/rspec-mocks/docs/basics/spies
rubocop-rspec:https://docs.rubocop.org/projects/rspec/en/latest/cops_rspec/#rspecmessagespies
【讨论】:
以上是关于RSpec:如何测试一个方法是不是被调用?的主要内容,如果未能解决你的问题,请参考以下文章
rspec 测试时,ActionMailer 方法调用在模块中返回 nil
当方法被意外调用的次数超过指定次数时,有没有办法从 rspec 获取堆栈跟踪?