Reputation: 2148
I have a method that looks like build_object(arg1, arg2, arg3, arg4, arg5)
I want to test this method when a certain value is passed for arg5.
I am trying something like
expect(my_method(p1, p2, p3, p4, bad5)).to raise_error(ArgumentError)
I get the following error:
ArgumentError:
The expect syntax does not support operator matchers, so you must pass a matcher to `#to`.
I am very new to Ruby and rspec testing, so any help is appreciated. Please explain what your answer is doing so that I learn.
Upvotes: 2
Views: 1739
Reputation: 10526
When writing a spec that checks for raise_error
, you must use the block-syntax {}
for expect
:
expect { my_method(p1, p2, p3, p4, bad5) }.to raise_error(ArgumentError)
There is a much more in-depth explanation in this question's answers, but you asked for an explanation so I'll give you an abbreviated one:
Most rspec matchers are value matchers. That means that something like this:
expect(some_method).to eq(value)
is really saying:
perform
some_method
and get its return value, then compare its return value tovalue
, and judge the success or failure of this spec on that comparison
When you're trying to test some piece of code that has a side effect, like possibly raising an exception, rspec needs to receive a block of code to run. It's a bit more like:
expect { <some block of code> }.to raise_error(ArgumentError)
perform
<some block of code>
, and then compare what happens when that code is executed to what is expected to happen, and judge the success or failure of this spec on that comparison
This answer for the above-linked question goes into detail about when you need to use expect {}
and when you need to use expect()
.
Upvotes: 6