RSpec Rails doesn’t render Rails views by default

April 12th, 2011 at 9:54 am • permalink5 comments

If you are using RSpec and RSpec Rails to test your Rails application, I strongly encourage you to keep reading this post because there’s a gotcha in the default configuration you might not expect, especially if you ever used the default Rails test framework before.

A couple of days ago I was notified about a but in a Rails application. The application crashed when trying to create a new record.

I changed the new action the day before, but I was sure all the tests passed and the action was covered with a pretty reasonable RSpec test suite. Moreover, the action method was one of the most simplest methods I have ever written.

def new
  @record = Model.new
end

I run the test suite, all green. I executed the page in the browser, it crashed.

My face when I discovered all tests passed but the action kept crashing.

After several minutes of debugging I discovered the culprit: RSpec (actually the RSpec Rails gem) doesn’t render the content of the action by default, like the common Rails functional tests do. In fact, @response.body always resulted in an empty string.

The view contained a statement like the following

<%= f.collection_select Model.all, :id, :name %>

that was misspelled and crashed when the template was rendered. But because RSpec doesn’t render the Rails views, the view was not covered by the tests at all.

The solution is simple and is called render_views.

To tell a controller to render the content of the view, simply call render_views.

require "spec_helper"

describe RecordsController do
  render_views

  describe "GET index" do
    # ...
  end
end

You can also enable render_views globally, in your spec_helper.rb file.

RSpec.configure do |config|
  config.render_views
end

The reason behind this choice is because RSpec Rails actually provides a special RSpec group called “view specs”.

describe "events/index.html.erb" do
  it "renders _event partial for each event" do
    assign(:events, [stub_model(Event), stub_model(Event)])
    render
    view.should render_template(:partial => "_event", :count => 2)
  end
end

According to the documentation, this is the right way to test Rails templates in RSpec. Honestly, I never really liked this feature and I tend to keep using controller specs — the RSpec equivalent of functional tests — (or alternative test tools) to test the views.

  1. Get the currently described class in RSpec
  2. User profile permalinks with Ruby on Rails (and Authlogic)
  3. New in Whois: Gem Testers
  4. Testing Rails: How to test Rails ActiveRecord Named Scopes
  5. The Road to Rails 3: make your Rails 2.3 project more Rails 3 oriented

Filed in Programming • Tags: , , ,

Comments

Rob says:

The part that confuses me is why you can’t call “render_views” inside of an actual view spec, but you can within a controller spec. It’s pretty strange

In a view spec it doesn’t make sense because the view already has access to the rendered content.

Ben says:

my bacon has been saved. thank you.

Tiago Alves says:

Thanks for pointing this out.

Just one small typo, in the code part where it starts with “require “spec_helper” … ” it should be written “render_views” just as you typed above.

Once again, thank you

You’re right! Fixed the typo, thank you very much.

Add a Comment




Follow Me
    Random Quote