Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec `should_receive` behaviour with multiple method invocation

Consider the following test:

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

The RSpec Documentation says:

Use should_receive() to set an expectation that a receiver should receive a message before the example is completed.

So I was expecting this test to pass, but it is not. It is failing with the following message:

Failures:

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

Is this expected behaviour? Is there a way to make this test pass?

I am using ruby 1.9.3p374 and rspec 2.13.1

like image 277
tdgs Avatar asked Mar 23 '23 10:03

tdgs


2 Answers

This should work:

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

The test was failing because you had set a precise expectation "a should receive :print with 'World'", but rspec noticed that the a object was receiving the print method with 'Hello' therefore it failed the test. In my solution, I allow the print method to be invoked with any argument, but it still keeps track of the call with "World" as argument.

like image 85
Ju Liu Avatar answered Mar 25 '23 23:03

Ju Liu


How about adding 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

Basically, allow(a).to_receive(:print) allows "a" to receive a "print" message with any arguments. Thus a.print('Hello') doesn't fail the test.

like image 42
Daniel Le Avatar answered Mar 25 '23 23:03

Daniel Le