Lets say I have method #sum
which takes an array and calculates sum of all elements. I'm stubbing it:
before do
expect(calculation_service).to receive(:sum?).with([1, 2, 3]) { 6 }
end
unfortunately my test suit passes array in random order. Because of that error is raised:
Failure/Error: subject { do_crazy_stuff! }
#<InstanceDouble() (CalculationService)> received :sum? with unexpected arguments
expected: ([1, 2, 3])
got: ([3, 2, 1])
Is it possible to stub method call ignoring order of an array elements? array_including(1, 2, 3)
does not ensure about array size, so it probably is not the best solution here
You can pass any RSpec matcher to with
, and contain_exactly(1, 2, 3)
does exactly what you want, so you can pass that to with:
expect(calculation_service).to receive(:sum?).with(contain_exactly(1, 2, 3)) { 6 }
However, "with contain exactly 1, 2, 3" doesn't read very well (and the failure message will be similarly grammatically awkward), so RSpec 3 provides aliases that solve both problems. In this case, you can use a_collection_containing_exactly
:
expect(calculation_service).to receive(:sum?).with(
a_collection_containing_exactly(1, 2, 3)
) { 6 }
You can also use the method match_array
. This way, you don't need to first split the elements of the array; instead, you can just use the whole array to match.
So you can use:
expect(calculation_service).to receive(:sum?).with(match_array([1, 2, 3])) { 6 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With