28 May 2009

Testing and generating HTML outside Rails views

At Reevoo we have cause to generate HTML snippets that are written to files rather than served up by a controller. It’s a pretty non-standard thing to do so I thought I’d share our methods (and if there’s a better way maybe someone will tell me).

First let’s look at the test:

(If you’re not familiar with Factory or should, take a look at Factory Girl and Shoulda)

 1 
 2 class WidgetHTMLGeneratorTest < ActiveSupport::TestCase
 3 
 4   include ActionController::Assertions::SelectorAssertions
 5 
 6   should "include the product name" do
 7     product = Factory(:product)
 8     html = WidgetHTMLGenerator.generate(product)
 9     assert_select HTML::Document.new(html).root, "div#product_name", product.name
10   end
11 
12 end
13 

Because we’re passing the HTML snippet in to assert_select we can assert our HTML markup in the same way we would in a controller or integration test, meaning we can test the markup that’s really important to us.

Now the implementation:

 1 
 2 class WidgetHTMLGenerator
 3 
 4   def self.generate(product)
 5     @product = product
 6     file_contents = File.read(File.join(Rails.root,'app','views','widget_html_generator','test.html.erb'))
 7     erb = ERB.new(file_contents)
 8     erb.result(binding)
 9   end
10 
11 end
12 

and the erb file:

1 
2 <div id='problem_name'><%= @product.name %></div>
3