简体   繁体   中英

Testing controller's redirect in RSpec

I have a rspec test testing a controller action.

class SalesController < ApplicationController
  def create
    # This redirect sends the user to SalesController#go_to_home
    redirect_to '/go_to_home'
  end

  def go_to_home
    redirect_to '/'
  end
end

My controller test looks like

RSpec.describe SalesController, type: :controller do
  include PathsHelper

  describe 'POST create' do
    post :create

    expect(response).to redirect_to '/'
  end
end

However, when I run the test it tells me that:

   Expected response to be a redirect to <http://test.host/> but was a redirect to <http://test.host/go_to_home>.
   Expected "http://test.host/" to be === "http://test.host/go_to_home".

/go_to_home will send the user to SalesController#go_to_home. How can I test that the response will eventually lead to the home page with the url http://test.host/ ?

Why are you expecting to be redirect to '/' in the specs? From the controller code you pasted you are going to be redirected to '/go_to_home' after hitting the create action

Try changing the specs to:

expect(response).to redirect_to '/go_to_home'

Edit:

Is this a real example or the code is just for sharing what you are trying to achieve? I don't think rspec will follow the redirect after going to '/go_to_home' and I think is fine.

If you are testing the create action it's ok to test that redirects to '/go_to_home' because that's what action is doing. Then you can do another test for the other action go_to_home and expect that redirects to root.

Are you calling the action 'go_to_home' from somewhere else?

Controller tests are effectively unit tests - you are testing the effect of calling a single action and what the expected behaviour of that action is.

The create action does return a response back with a status code of 302 and includes in the header a Location indicating the new URI, which in the case of calling create would be Location: http://localhost/go_to_home

This is as far as the controller test goes. It has emulated a call made from a browser to the create action and received the initial redirection.

In the real world of course the browser would then navigate to the given location and would then hit the go_to_home action but this is beyond the scope of controller tests ... this is in the domain of integration testing.

So, either,

  1. Create an integration test to initially call the create action, follow the redirection and test that you end up at '/'.
  2. Change the controller test to expect(response).to redirect_to '/go_to_home'
  3. Change the create action to redirect directly to '/'

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