Rspec: expect(response).to have one of several valid values

50 views
Skip to first unread message

Ralph Shnelvar

unread,
Jul 15, 2017, 8:43:01 PM7/15/17
to Ruby on Rails: Talk
I'm a novice at Rspec.


Let's say I have
expect(response).to have_http_status(200)

But what I want is to say that either 200 or 302 is valid.

How would I do that?


Assume
(byebug) response.status
302

I've tried
expect(response).to (have_http_status(200) || have_http_status(302))

While syntactically valid, this doesn't work because have_http_status(200)will throw an exception before it gets to the have_http_status(302) .


Is this the right forum to ask this question?

Dave Aronson

unread,
Jul 15, 2017, 9:48:49 PM7/15/17
to rubyonra...@googlegroups.com
On Saturday, July 15, 2017, Ralph Shnelvar <ral...@dos32.com> wrote:

I've tried
expect(response).to (have_http_status(200) || have_http_status(302))

While syntactically valid, this doesn't work because have_http_status(200)will throw an exception before it gets to the have_http_status(302) .

Maybe something like "expect([200, 302]).to include response.status_code"?  (Not sure of exact syntax as I've been away from RSpec for a while and am not at my coding computer.)


--
Sent from Gmail Mobile; please excuse top posting, typos, etc. :-(

Ralph Shnelvar

unread,
Jul 15, 2017, 10:41:14 PM7/15/17
to Ruby on Rails: Talk
Very close!


expect([200, 302]).to include response.status

Thank you so much!  Your suggestion gave me a whole new understanding of Rspec

Ralph

Frederick Cheung

unread,
Jul 18, 2017, 10:25:09 AM7/18/17
to Ruby on Rails: Talk


On Sunday, July 16, 2017 at 1:43:01 AM UTC+1, Ralph Shnelvar wrote:

expect(response).to (have_http_status(200) || have_http_status(302))

While syntactically valid, this doesn't work because have_http_status(200)will throw an exception before it gets to the have_http_status(302) .

This doesn't work, but not for the reason you think. Calling have_http_status(200) never raises an exception. It creates a matcher object that the `to` method uses. The ruby || operator (one of few things that can't be overridden) evaluates to the first non falsy thing, so your code is the same as 

expect(response).to (have_http_status(200) || have_http_status(302))


so expect(response).to have_http_status(200) | have_http_status(302)

should work, as would things like

expect(3).to eq(2) | eq(3)

This works because | and & are overridable methods and have been defined on matchers to mean "create me a new matcher which matches if either argument matches" (or both match in the & case)

Fred
Reply all
Reply to author
Forward
0 new messages