Rspec Testing Redirect to Url with Get Params

RSpec testing redirect to URL with GET params

From the documentation, the expected redirect path can match a regex:

expect(response).to redirect_to %r(\Ahttp://example.com)

To verify the redirect location's query string seems a little bit more convoluted. You have access to the response's location, so you should be able to do this:

response.location
# => http://example.com?foo=1&bar=2&baz=3

You should be able to extract the querystring params like this:

redirect_params = Rack::Utils.parse_query(URI.parse(response.location).query)
# => {"foo"=>"1", "bar"=>"2", "baz"=>"3"}

And from that it should be straightforward to verify that the redirect params are correct:

expect(redirect_params).to eq("foo" => "1", "baz" => "3", "bar" => "2")
# => true

If you have to do this sort of logic more than once though, it would definitely be convenient to wrap it all up into a custom rspec matcher.

Rspec rails: How do I test if a controller action redirects correctly to itself with modified params once?

For the second one I guess you can test the following things:

expect(response).to render_template(:your_template)

Just add the expected template, if you want no redirection just add the template where you expect to stay.

For the first one, I am not sure to really understand what you need but I try to advise you the following code:

describe SearchController, type: :request do
# ...
it 'should do a redirect' do
get "/search", deprecated_param: 'yes'
expect(response).to redirect_to("http://mydomain.test/search?new_param=yes")
follow_redirect!
expect(response).to have_http_status(200)
expect(response).to render_template(:your_template) #just to be sur you are on the expected page
end

follow_redirect! follow a single redirect response. If the last response was not a redirect, an exception will be raised.

Rspec view test with url parameters

Because these are redirects, controller testing with render_views will
not work.

Nope, you are just doing it wrong.

If StaticpagesController#dashboard accepts url parameters you should test how it responds to said parameters in the controller spec for StaticpagesController.

RSpec.describe StaticpagesController, type: :controller do 
describe 'GET #dashboard' do
render_views
it "does something with the x parameter" do
get :dashboard, x: 'hello!'
expect(response.body).to match 'hello!'
end
end
end

Similarly you should test that PlansController#some_action includes the correct parameters in the response.

I would argue that your view specs problems are telling you that you have a code smell in your views. In MVC your controllers are responsible for taking input and passing it to views and models. Isolating your views from dealing directly with parameters means that the parameter handling it not duplicated all over your app.

Use locals in your controllers to pass variables to your views and avoid using params in your views.

It makes for a better design and easier tests:

describe "rendering locals in a partial" do
it "displays the widget" do
widget = stub_model(Widget, :name => "slicer")
render :partial => "widgets/widget.html.erb", :locals => {:widget => widget}
rendered.should contain("slicer")
end
end

rspec redirect_to with multiple parameters

The documentation is misleading. Internally, assert_redirected_to calls normalize_argument_to_redirection, which (when a hash is given as the argument) calls url_for before performing the comparison. Basically, a partial match will work only if the route has the default pattern :controller/:action/:id, and your asserted path is a hash with the controller or controller and action as keys.

Testing requests that have redirects in RSpec

You can check that a post was created and that a user was redirected, if params are valid. And if you have any validation in the Post model, it is good idea to test invalid params:

RSpec.describe 'PostsController', type: :request do
describe 'POST #create' do
context 'with valid params' do
it 'creates a new post' do
expect { post posts_path, params: { post: valid_attributes } }.to change(Post, :count).by(1)
expect(response).to redirect_to post_path(Post.last)
end
end

context 'with invalid params' do
it 'does not create a new post' do
expect { post posts_path, params: { post: invalid_attributes } }.not_to change(Post, :count)
expect(response).to have_http_status 200
end
end
end
end

Rspec redirect to testing

Assuming that @params will create a valid Micropost (otherwise .save will fail and you'll be rendering :edit)...

it "redirects to index on successful save" do
post :create, :micropost => @params.attributes
response.should be_redirect
response.should redirect_to(assigns[:micropost])
end

it "renders :edit on failed save" do
post :create, :micropost => {}
response.should render ... # i don't recall the exact syntax...
end

Rspec check the template after a redirect

When you're testing create action you should just check correctness of redirect. In this action you're not actually rendering edit template, but you're just making redirect to the edit path of created entity. So this is the thing you should check.

describe "#create" do
it "redirects to the edit path" do
post :create, user: FactoryGirl.attributes_for(:user)
expect(response).to redirect_to(edit_admin_user_path(User.last))
end
end

Then you should have another test for edit action, where you're checking template rendering. That will mean that after redirect in create action you also will see the proper template.



Related Topics



Leave a reply



Submit