Going backwards with RSpec is a pain. By backwards I mean, write the specs after the specifications (my application) already exist. It feels like I'm re-writing all the code I just wrote. I can see the value in writing the specifications as we bring more team members on board and now my mindset is such that I feel like I'm writing documentation to support them as we introduce them to the code base. The real pain started to set in when I had this small problem. The problem I'm having is that rspec is returning an error every time it encounters a method in the view that takes advantage of the polymorphic helpers AND does not pass the appropriate instance variables. Rails by default will allow you to call these methods without passing arguments to it. Here is the error:
1
2
3
4
5
6
7
8

ActionView::TemplateError in 'Edit Artist Page should render the edit artist form'
label_artist_url failed to generate from {:action=>"show", :controller=>"artists"} - you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: ["labels", :label_id, "artists", :id] - are they all satisfied?
On line #3 of app/views/artists/edit.rhtml

    1: <h1>Editing artist</h1>
    2: 
    3: <% form_tag label_artist_path, :method => :put do %>
By providing label_artist_path with its arguments this error goes away:

label_artist_path(@label, @artist)
This to me however adds unnecessary noise to the already easy clutter erb syntax and I would much rather just use this method without having to pass its arguments. There is also another option: stub out the label_artist_path method. My problem with this is that I feel like I'm not really testing my views fully and it will be hard to maintain considering I use these methods everywhere in my views. I could write a module that would include these methods, but this tends to be a big no-no in the rspec philosophy as you are hiding away some of the specifications. I'm thinking the best solution is to patch whatever the problem is in rspec, but I'm not sure where to start. I had a long discussion about this with David Chelimsky about this topic on the rspec mailing list and continued on the irc channel. I even posted a bug report on it here. We were trying to pinpoint where in rails these instance variables get sent to the helpers. He made the suggestion of adding the following code into my before method:

(class << @controller; self; end).send :include, ActionView::Helpers::UrlHelper
Which gives a completely different error:
1
2
3
4
5
6
7
8
9

ActionView::TemplateError in 'Edit Artist Page should render the edit artist form'
You have a nil object when you didn't expect it!
The error occurred while evaluating nil.url_for
On line #3 of app/views/artists/edit.rhtml

    1: <h1>Editing artist</h1>
    2: 
    3: <% form_tag label_artist_path, :method => :put do %>
For some reason the controller is not being set and that is basically where we left off. If anyone has any solutions, please comment! I will keep this post updated.

1 Response to “RSpec and RESTful Polymorphic Url Helpers”

  1. mike Says:
    I am struggling with this same issue. The workaround I came up with is to mock out the calls to url_for and then to verify the routes in the controller specs. Alternatively you can integrate_views in the controller specs and test your views from the controller specs.

Sorry, comments are closed for this article.