You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Generally speaking, it seems desirable to convert redirect_to to render.
This is because redirect_to reloads the whole app, but render just continues executing. Until recently it seemed undesirable to attempt this conversion on MO, though, because render doesn't update the browser url by default. But we've recently learned that you can
Note that render generates a different response by the app: it gives a 204 where redirect_to gives 302.
This means:
assert_redirected_to will not work: it checks for a 300 code and returns false unless the response is actually a redirect. (assert_template can work provisionally, more below.)
flash will have already been rendered by the time the test checks the response. So assert_flash may not work; instead test for the presence of the flash message in the rendered HTML.
Test expectations have to be adjusted to allow for these differences. But there's another big advantage from converting: Controller tests without assert_redirected_to are a big step closer to integration tests. If we move controller logic to service objects (with their own tests), we will still need to write integration test coverage.
At this point, i maybe can imagine why the Rails maintainers thought it would be no big deal to eliminate controller tests: if they assumed everyone had been keeping up with the redirect/render evolution, then they'd have an easy time with the conversion. As long as controllers are redirecting, though, the test syntax is quite different and it's a daunting change. Converting to render makes the switch easier.
How to proceed?
Big moves
The first priority may be refactoring controller test methods that hinge on redirects, like requires_login, post_requires_user, etc. Change these to pass kwargs including a redirect/render switch that defaults to redirect, and develop a parallel set of assertions that does not assert redirects, but rather tests for HTML via renders.
Change ApplicationController methods that redirect, like show_index_of_objects, to render, but wow, lots of index tests will need updating.
Gotchas
render("template") renders an action's template, it doesn't goto the other action. So you need to set up the same ivars as the action that usually renders the template
Templates in redirected views must use partial paths relative to the /views directory, or the calling action will look for the partial in its own template directory
Then, we can start converting controllers and tests. Working outline:
Change the controller action to render, if that's appropriate.
Change the relevant controller test assertion from assert_redirected_to to assert_template
Add an HTML ID to a primary div on the template.erb files — these should be unique so they indicate the page template via HTML
Replace assert_template with an assert_select(“#html_element_id")
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Generally speaking, it seems desirable to convert
redirect_to
torender
.This is because
redirect_to
reloads the whole app, butrender
just continues executing. Until recently it seemed undesirable to attempt this conversion on MO, though, becauserender
doesn't update the browser url by default. But we've recently learned that you canand it will update the browser url.
Note that
render
generates a different response by the app: it gives a204
whereredirect_to
gives302
.This means:
assert_redirected_to
will not work: it checks for a300
code and returns false unless the response is actually a redirect. (assert_template
can work provisionally, more below.)flash
will have already been rendered by the time the test checks the response. Soassert_flash
may not work; instead test for the presence of the flash message in the rendered HTML.Test expectations have to be adjusted to allow for these differences. But there's another big advantage from converting: Controller tests without
assert_redirected_to
are a big step closer to integration tests. If we move controller logic to service objects (with their own tests), we will still need to write integration test coverage.At this point, i maybe can imagine why the Rails maintainers thought it would be no big deal to eliminate controller tests: if they assumed everyone had been keeping up with the redirect/render evolution, then they'd have an easy time with the conversion. As long as controllers are redirecting, though, the test syntax is quite different and it's a daunting change. Converting to
render
makes the switch easier.How to proceed?
Big moves
requires_login
,post_requires_user
, etc. Change these to pass kwargs including a redirect/render switch that defaults toredirect
, and develop a parallel set of assertions that does not assert redirects, but rather tests for HTML via renders.ApplicationController
methods that redirect, likeshow_index_of_objects
, torender
, but wow, lots of index tests will need updating.Gotchas
render("template")
renders an action's template, it doesn'tgoto
the other action. So you need to set up the same ivars as the action that usually renders the template/views
directory, or the calling action will look for the partial in its own template directoryThen, we can start converting controllers and tests. Working outline:
render
, if that's appropriate.assert_redirected_to
toassert_template
assert_template
with anassert_select(“#html_element_id")
Beta Was this translation helpful? Give feedback.
All reactions