Read more

Spec "content_for" calls in helpers

Arne Hartherz
March 05, 2012Software engineer at makandra GmbH

This only applies to RSpec below version 1.3.2. The issue has been fixed in RSpec 1.3.2, and most likely RSpec 2 and later versions.


Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

When you have a helper that calls content_for and want to check its behavior you should probably write a feature instead. If you still want to do it, mind the following.

Consider this helper:

module LayoutHelper
  def title(string)
    content_for :title, string
    string
  end
end

Somewhere in the layout we'd then say something like this: <title><%= yield :title %></title>.

Inspecting prepared content for content_for

If you want to inspect what the helper prepared for the view, you need to hack a bit:

it 'should work'
  helper.title('Hello Universe')
  helper.instance_variable_get('@content_for_title').should == 'Hello Universe'
end

Unfortunately, this may only work once. RSpec instanciates the helper object only once, thus keeping instance variables -- and since content_for always attaches, any second spec will break looking at @content_for_title.

Checking this more than once

When your application is up, you will actually get a fresh helper attached to the view each time your content is being rendered. We want something similar, so we define our own helper object:

let :helper do
  Spec::Rails::Example::HelperExampleGroup::HelperObject.new.tap do |helper|
    helper.send :extend, LayoutHelper
  end
end

it 'should work'
  helper.title('Hello Universe')
  helper.instance_variable_get('@content_for_title').should == 'Hello Universe'
end

it 'should still work'
  helper.title('Hello World')
  helper.instance_variable_get('@content_for_title').should == 'Hello World'
end

This applies to Rails 2. Maybe RSpec 2 / Rails 3 are smarter.

Posted by Arne Hartherz to makandra dev (2012-03-05 16:36)