Reputation: 8517
I'm writing an expectation which checks whether a method is called two times with different arguments and returns different values. At the moment I'm just writing the expectation twice:
expect(ctx[:helpers]).to receive(:sanitize_strip).with(
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>},
length: nil
).and_return('String description and newline')
expect(ctx[:helpers]).to receive(:sanitize_strip).with(
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>},
length: 15
).and_return('String descr...')
I wonder if I can use receive ... exactly ... with ... and_return ...
instead; something like:
expect(ctx[:helpers]).to receive(:sanitize_strip).exactly(2).times.with(
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>},
length: nil
).with(
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>},
length: 15
).and_return('String descr...', 'String description and newline')
The code above doesn't work, it raises the following error:
1) Types::Collection fields succeeds
Failure/Error: context[:helpers].sanitize_strip(text, length: truncate_at)
#<Double :helpers> received :sanitize_strip with unexpected arguments
expected: ("String\n<a href=\"http://localhost:3000/\">description</a> <br/>and newline\n<br>", {:length=>15})
got: ("String\n<a href=\"http://localhost:3000/\">description</a> <br/>and newline\n<br>", {:length=>nil})
Diff:
@@ -1,3 +1,3 @@
["String\n<a href=\"http://localhost:3000/\">description</a> <br/>and newline\n<br>",
- {:length=>15}]
+ {:length=>nil}]
Is there a way to use receive ... exactly ... with ... and_return ...
with different with
arguments?
Upvotes: 2
Views: 1803
Reputation: 75
Without using an extra gem, you could call the normal expect ... to receive ... with ... and_return ...
with variables from inside an each
block:
describe '#sanitize_strip' do
let(:html) do
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>}
end
let(:test_data) do
[
[[html, length: nil], 'String description and newline'],
[[html, length: 15], 'String descr...']
]
end
it 'returns sanitized strings stripped to the number of characters provided' do
test_data.each do |args, result|
expect(ctx[:helpers]).to receive(:sanitize_strip).with(*args).and_return(result)
end
# Trigger the calls to sanitize_strip
end
end
Upvotes: 1
Reputation: 4900
There's an rspec-any_of
gem that allows for the following syntax by prodiding all_of
argument matcher:
expect(ctx[:helpers]).to receive(:sanitize_strip).with(
%{String\n<a href="http://localhost:3000/">description</a> <br/>and newline\n<br>}
all_of({length: 15}, {length: nil})
)
.and_return('String descr...', 'String description and newline')
.twice
Upvotes: 1