【问题标题】: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 听起来它应该这样做,但进一步阅读它听起来并不完全是它的作用。

【问题讨论】:

标签: ruby-on-rails ruby rspec


【解决方案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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      相关资源
      最近更新 更多