[rspec-users] render_template expectation - surprising pattern matching issue

Phillip Koebbe phillipkoebbe at gmail.com
Mon Jul 26 12:22:21 EDT 2010


  On 2010-07-26 11:12 AM, Timo Rößner wrote:
> Hey guys,
>
> we just found out by accident that rspec seems to apply a pretty
> confusing mechanism to ensure that a certain template is rendered.
>
> To clarify, consider this standard controller spec:
>
>    # working
>    it 'GET edit' do
>      get :edit, :id =>  '37'
>      response.should render_template(:edit)
>    end
>
> So far, so good. Now to the surprising part:
>
>    # NOT working
>    it 'GET edit' do
>      get :edit, :id =>  '37'
>      response.should render_template(:eda)
>    end
>
>    # ->  here's the surprise:  working
>    it 'GET edit' do
>      get :edit, :id =>  '37'
>      response.should render_template(:edi)
>    end
>
> Apparently rspec uses a pretty generous pattern matching to ensure
> that a certain template is rendered.
>
> If I had to guess, I'd say that's because rspec wants to ignore path /
> namespacing / different file endings (html.haml, html.erb and so on).
>
> I still think this approach is suboptimal for two reasons:
>
> 1.) It violates the principle of least suprise, this behaviour is more
> like "the biggest surprise possible" - who would have thought that
> example nr.3 is working?
>
> 2.) I can easily imagine a situation where 2 or more actions start
> with the same letters. In this case, what would happen if you changed
> the "render_template"-call (i.e. shortening the template name) and
> remove one action.
> Wouldnt the specs still be green although one view would be completely
> missing?
>
> 2 questions:
>
> 1.) Is this a bug or a feature?
>
> 2.) Why not change the pattern matching that it still ignores paths
> and file endings, but at least tries to match the expected template
> exactly to the rendered template?
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

I've experienced a bit of pain with making sure the right view gets 
rendered. Initially, I was doing essentially what you are doing, but 
noticed that the specs would pass even if I didn't render the view (ie, 
the view wasn't there). Then I discovered integrate_views, which helped 
immensely in that regard, until I later discovered that I had to mock 
and stub everything that the view expected. Hated that. I've since 
started using something that is not quite as unobtrusive as I'd like, 
but I much prefer the results. I don't integrate_views any more and I 
set an expectation on the controller to render. Something like:

describe 'get :index' do
   it 'should render the index view' do
     controller.should_receive(:render).with(:index)
     get :index
   end
end

The unfortunate part of this is that I must then explicitly render the 
view in the controller action:

def index
   ...
   render :index
end

I wish I didn't have to do it that way, but so far, this is the best I 
can do to balance specing the controller with keeping things isolated. I 
openly admit there might be a better solution and I may very well have 
overlooked something obvious. I didn't spend a lot of time trying to get 
this figured out correctly, so there may be a better way.

Peace,
Phillip


More information about the rspec-users mailing list