具有多个方法调用的RSpec`utu_receive`行为

时间:2013-06-25 14:08:56

标签: ruby testing rspec rspec2

考虑以下测试:

class A
  def print(args)
    puts args
  end
end

describe A do
  let(:a) {A.new}

  it "receives print" do
   a.should_receive(:print).with("World").and_call_original

   a.print("Hello")
   a.print("World")
 end
end

RSpec Documentation说:

  

使用should_receive()设置接收者应该收到的期望   示例完成之前的消息。

所以我期待这个测试通过,但事实并非如此。它失败了以下消息:

Failures:

1) A receives print
 Failure/Error: a.print("Hello")
   #<A:0x007feb46283190> received :print with unexpected arguments
     expected: ("World")
          got: ("Hello")

这是预期的行为吗?有没有办法让这个测试通过?

我正在使用 ruby​​ 1.9.3p374 rspec 2.13.1

4 个答案:

答案 0 :(得分:4)

这应该有效:

class A
  def print(args)
    puts args
  end
end

describe A do
  let(:a) {A.new}

  it "receives print" do
   a.stub(:print).with(anything())
   a.should_receive(:print).with("World").and_call_original

   a.print("Hello")
   a.print("World")
 end
end

测试失败了,因为你已经设定了一个精确的期望“应该收到:打印'世界'”,但是rspec发现一个对象正在接收带有'Hello'的print方法,因此它失败了测试。在我的解决方案中,我允许使用任何参数调用print方法,但它仍然以“World”作为参数跟踪调用。

答案 1 :(得分:2)

这个怎么样?

class A
  def print(args)
    puts args
  end
end

describe A do
  let(:a) {A.new}

  it "receives print" do
   a.should_receive(:print).with("World").and_call_original
   # it's important that this is after the real expectation
   a.should_receive(:print).any_number_of_times

   a.print("Hello")
   a.print("World")
 end
end

它增加了第二个期望,您可能希望避免。但是,考虑到@vrinek的问题,该解决方案具有提供正确失败消息的优点(预期:1次,收到:0次)。干杯!

答案 2 :(得分:1)

如何添加allow(a).to receive(:print)

require 'rspec'

class A
  def print(args)
    puts args
  end
end

describe A do
  let(:a) { described_class.new }

  it 'receives print' do
    allow(a).to receive(:print)
    expect(a).to receive(:print).with('World')

    a.print('Hello')
    a.print('World')
  end
end

基本上,allow(a).to_receive(:print)允许&#34; a&#34;接收&#34;打印&#34;带有任何参数的消息。因此a.print('Hello')没有通过测试。

答案 3 :(得分:0)

should_receive不仅检查调用了预期的方法,还检查了调用的意外方法。只需为您期望的每个调用添加一个规范:

class A
  def print(args)
    puts args
  end
end

describe A do
  let(:a) {A.new}

  it "receives print" do
   a.should_receive(:print).with("World").and_call_original
   a.should_receive(:print).with("Hello").and_call_original

   a.print("Hello")
   a.print("World")
 end
end