How to Unit Test a custom Rails Form Builder

I recently created my first custom Rails builder.  It was very easy to do.



First, create a class that inherits from ActionView::Helpers::FormBuilder and then you can either write your own methods or overwrite the built in text_field, check_box, radio_button, etc.

class MyFirstFormBuilder < ActionView::Helpers::FormBuilder

...

end



Then, when using a form you can specify the builder (or set your builder to be the default in your config file)

<% form_for @post, :builder => MyFirstFormBuilder do |f| %>

...

<% end %>


That's all great and well documented, but I had a hard time finding the best way to write automated tests for the builder.  I was looking for a way to write unit tests directly against this class, rather than relying on a view and controller and using the heavier functional test framework.  Here is how it is done:



require File.expand_path('../../test_helper',  __FILE__)



class MyFirstFormBuilderTest < ActionView::TestCase

tests ActionView::Helpers::FormHelper



def protect_against_forgery?

false

end



test_error_messages_format_when_no_errors

assert @post.valid?



form_for(:advertiser, @post, :url => "/foo",
                                 :builder => MyFirstFormBuilder) do |f|

concat f.error_messages

end



assert_dom_equal "<form action="/foo" method="post"></form>",

output_buffer

end

end




The keys are:

1. Inherit your unit test from ActionView::TestCase

2. tests ActionView::Helpers::FormHelper is key to allow you to directly call helper methods that you normally would call from an ERB template file (such as form_for)

2b. I had to define protect_against_forgery? in order to call form_for

3. output_buffer is an accessor of ActionView::TestCase, which is an HTMLDocument object of the output

4. assert_dom_equal is handy to compare HTML output for equality (ignoring attribute order and single quotes versus double quotes)
This is an amp-user-notification. It uses local storage to store the dismissed state.
Call Tracking test with extra params: 800-123-4567