Reputation: 1013
I have this Rspec test for a rails app
describe '.move_probes_to_master_list' do
let(:as) { create_list :a, 3, }
let(:bs) { create_list :b, 3 }
it 'sums the volumes' do
active_as= [as[1], as[2]]
b_ids = [2, 3]
expect_any_instance_of(A)
.to receive(:required_volume).twice.with(b_ids)
expect_any_instance_of(A)
.to receive(:update_move_to_master_list).twice
expect(A.calculate_volume(active_as)).to eq(true)
end
end
Basically I call A.calculate_volume
and inside this class method, I want to ensure that some member of the A
class is recieving some other messages as well. I don't want to stub out those methods, I want them to run as normal, but I just want to verify that the methods are being called.
This is being run in a loop, so I don't know exactly what instances I'll be dealling with, but I want to make sure that both messages are called on some members (but not necessarily the same member both times) of the A
class twice in total.
If I remove the expect_any_instance_of(A).to receive
expectations everything runs fine and the test passes.
If I keep them, the method call fails and the test breaks.
I tried adding and_call_original
but I feel like I'm shooting in the dark because the docs aren't clear on how these methods actually operate.
So how can I verify that an instance of some class recieves a message n
times without changing anything else about the method call?
Am I missing the point of expect to receive here? It's not obvious to me why it would stub anything in the first place.
Upvotes: 7
Views: 9035
Reputation: 640
I know this doesn't exactly answer your question "how to continue execution", but you should be able to break this test into three distinct tests and create a more clear set of tests while not having to worry about calling the original as such:
describe '.move_probes_to_master_list' do
let(:as) { create_list :a, 3, }
let(:active_as) { [as[1], as[2]] }
let(:bs) { create_list :b, 3 }
let(:b_ids) { [2, 3] }
subject { A.calculate_volume(active_as) }
it 'sums the volumes' do
expect(subject).to eq(true)
end
it 'calls #required_volumen twice' do
expect_any_instance_of(A)
.to receive(:required_volume).twice.with(b_ids)
subject
end
it 'calls updates_moves_to_master_list twice' do
expect_any_instance_of(A)
.to receive(:update_move_to_master_list).twice
subject
end
end
Upvotes: 1
Reputation: 882
You could spy on the method like this:
allow(A).to receive(:calculate_volume).and_call_original
Then you could test that calculate_volume
has been called like this:
expect(A).to have_received(:calculate_volume)
This way the original method will be called and there would be no stubbing but spying.
Upvotes: 11