I have a page dashboard.html.erb
that may be redirected to from several different controllers/actions. When it receives the redirect, it also receives several url parameters.
Controller code:
class PlansController
def some_action
redirect_to dashboard_path(show: "default", cool_array: ["test", "test"])
end
end
class StaticpagesController
def dashboard
end
end
View code:
<% if cool_array %>
<% cool_array.each do |a| %>
<li><%= a %></li>
<% end %>
<% end %>
<script>
var show = getParamFromURL("show")
// some sort of function that returns the value of the show param, in this case, "default"
if (show == "default") {
$("#default").addClass("show");
} else {
$("#other").addClass("hidden");
}
</script>
Because these are redirects, controller testing with render_views
will not work. Therefore, I had thought to construct my tests so that the controller spec tests that the right parameters are being passed, and the view spec tests that if certain parameters are present, the right css classes are present, or whatever. But in my view spec, I'm having trouble simulating the passing of parameters.
This seems to be the only other question out on this that I found: RSpec View testing: How to modify params?
But none of the solutions have worked for me; I'm not sure in this case I need a helper... which seems a bit contrived...
I have tried (from the linked SO question above):
before do
controller.request.path_parameters[:cool_array] = ["test","test"]
end
# => ActionView::Template::Error:
# undefined local variable or method `cool_array' for #<#<Class:0x007fe2d9815100>:0x007fe2d90a62e8>
# thrown by line in view file with <% if cool_array %>
before do
view.stub(:params).and_return({cool_array: ["test", "test"]})
end
# => ActionView::Template::Error:
# undefined local variable or method `cool_array' for #<#<Class:0x007fe2d9815100>:0x007fe2d90a62e8>
# thrown by line in view file with <% if cool_array %>
helper.params = {:cool_array => ["test", "test"]]}
# honestly not even sure this is right, because it can only go into a describe block (not a before, not an it) and then it throws:
# NoMethodError:
# undefined method `params=' for #<#<Class:0x007fd7cc8f4930>:0x007fd7cc8a5060>
And they all fail with:
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.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 usingparams
in your views.It makes for a better design and easier tests: