简体   繁体   中英

Testing redirect_back with Rspec in Rails 5

I'm upgrading my Rails 5 app now, and currently overcoming the following deprecation:

DEPRECATION WARNING: `redirect_to :back` is deprecated and will be removed from Rails 5.1. Please use `redirect_back(fallback_location: fallback_location)` where `fallback_location` represents the location to use if the request has no HTTP referer information. (called from block (3 levels) in <top (required)> at /path/to/some/controller_spec.rb:74)

No worries. Just switched the controller to the new format:

redirect_back(fallback_location: home_path, message: "Some error")

However, the warning doesn't disappear, because the test still looks at :back , like this:

expect(response).to redirect_to(:back)

I don't see any preferred way to overcome this deprecation. Is there another way to test this without manually specifying a HTTP_REFERER in my test?

Well, I looked into the rails / rspec-rails source a bit, and it looks pretty bleak. Here's the new redirect code:

def redirect_back(fallback_location:, **args)
  if referer = request.headers["Referer"]
    redirect_to referer, **args
  else
    redirect_to fallback_location, **args
  end
end

And rspec-rails specifically tests the redirect location, like this:

@scope.assert_redirected_to(@expected)

That would imply that if we don't know the redirect location (or at least the fallback location), we're pretty much out of luck. The rspec matcher itself is just testing whether the response object responds to redirect? with true, but since Rails redirects don't currently track whether they originated from redirect_to or redirect_back , there's no distinguishing case.

It seems that currently, given the following redirect:

redirect_back(fallback_location: "/foo/bar")

The best controller test we can manage is testing for:

expect(response).to redirect_to("/foo/bar")

Which will fail if we manage to provide a Referer header at some point.


More updates! I asked around rspec-rails , and they're not interested in supporting an update on this. It's a reasonable stance, given I'm really just looking for a clean syntax to do the assertion. Instead, I've changed over to this:

let(:back) { 'http://google.com' }
before { request.env['HTTP_REFERER'] = back }

And now I can retain the nice format of:

 expect(response).to redirect_to(back)

For now there isn't anything to address this for test suites. But the change from redirect_to(:back) to redirect_back has a history for a case when HTTP_REFERER is not set. If we are using redirect_back then we should test edge cases for this.

  1. When HTTP_REFERER is set
  2. When HTTP_REFERER is not set

In both scenarios we can't skip setting HTTP_REFERER but thats for a genuine reason.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM