Jakub Arnold
Jakub Arnold

Reputation: 87210

How to say "should_receive" more times in RSpec

I have this in my test

Project.should_receive(:find).with(@project).and_return(@project)

but when object receive that method call two times, I have to do

Project.should_receive(:find).with(@project).and_return(@project)
Project.should_receive(:find).with(@project).and_return(@project)

Is there any way how to say something like

Project.should_receive(:find).with(@project).and_return(@project).times(2)

Upvotes: 140

Views: 91113

Answers (4)

Staelen
Staelen

Reputation: 7841

This is outdated. Please check Uri's answer below

for 2 times:

Project.should_receive(:find).twice.with(@project).and_return(@project)

for exactly n times:

Project.should_receive(:find).exactly(n).times.with(@project).and_return(@project)

for at least n times:

Project.should_receive(:msg).at_least(n).times.with(@project).and_return(@project)

more details at https://rspec.info/documentation/3.5/rspec-mocks/RSpec/Mocks/MessageExpectation.html under Constraining Receive Counts

Upvotes: 240

Prasanna
Prasanna

Reputation: 11544

@JaredBeck pointed out. The solution didn't work for me on any_instance call.

For any instance i ended up using stub instead of should_receive.

Project.any_instance.stub(:some_method).and_return("value")

This will work for any no. of times though.

Update: Syntax is deprecated. See comment.

Upvotes: 0

amnsan
amnsan

Reputation: 51

should_receive, as opposed to any_instance, expects that the class receives message the specified number of times.

any_instance on the other hand is generally used for stubbing a method.

So the first case is an expectation that we would like to test, while the second one is getting past a method to the next line so we can move on.

Upvotes: 1

Uri Agassi
Uri Agassi

Reputation: 37409

The new expect syntax of rspec will look like this:

for 2 times:

expect(Project).to receive(:find).twice.with(@project).and_return(@project)

for exactly n times:

expect(Project).to receive(:find).exactly(n).times.with(@project).and_return(@project)

for at least n times:

expect(Project).to receive(:msg).at_least(n).times.with(@project).and_return(@project)

Upvotes: 100

Related Questions