Testing the Postcode Ajax Controller in Rails

So, for instance, the first test I have is that when I enter a valid postcode, I get a result back:

def test_can_retrieve_postcodes_for_ajax_finder      xhr :post, :lookup_postcode, :postcode => "SW1A 1AA"          assert_response :success      assert_select_options "selected_address", 1    end    def lookup_postcode      @results = PostcodeLookup.find(        params[:postcode]        )      render_partial("postcode_results")    end

In this test, all I’m looking for is that we have a successful response and that we have a `select` html tag that contains 1 option (the address for our postcode). The helper assertion method looks as follows:

def assert_select_options(name, option_count)  assert_tag :tag => "select",    :attributes => {:id => name},    :children => {      :count => option_count,      :only => {:tag => "option"}      }end

This raises an important question—one of determinism and roles. In our tests, we’re not so much interested in the actual postcode results, we’re just interested that given a particular postcode, we have a single result. We want to test that our controller uses the postcode lookup code correctly (encapsulated through a separate set of classes I’ve written).

Once again, a fine example of where to mock. Not only do we prevent dependency on the web-service being accessible and running, we improve unit test performance, and we can guarantee results.

I’ll be writing another post on how I went about developing the postcode lookup aspect of the site (since I think mocking and test-first is something that Rails makes so easy it’s an incredibly valuable part of the framework).

So, our postcode lookup class guarantees us that with certain postcodes we will have guaranteed results. Which lets us also test with a bad postcode:

def test_not_filled_when_bad_address_selected  xhr :post, :fill_address, :selected_address => 1101010end

assert_response :successassert_equal "text/javascript", @response.headers["Content-Type"]assert !/Buckingham Palace/.match(@response.body)

This covers the display of possible addresses for a postcode. Now, to ensure that when we select an address we are given code that will change our input fields to contain the correct information.

Since we’re using inline RJS for this aspect of the application, we want to check that when we perform the lookup, our address entry `div` is replaced with the updated markup, containing our address.

RJS is rendered as JavaScript that will be interpreted and executed by the browser, so we want to assert that our response is marked as `text/javascript`. We then want to test that we can find our input tag that contains the first line of the address.

def test_when_selecting_address_address_fields_populated  xhr :post, :fill_address, :selected_address => 1end

assert_response :successassert_equal "text/javascript",   @response.headers["Content-Type"]assert /Buckingham Palace/.match(  @response.body)

As you can see we use a rather ugly regular expression to match on the address, rather than re-use the lovely `assert_tag` helper. Although it works, it’s not especially pretty and is something I’m looking to change. Has anyone tried doing this already? If not, I’ll let you know how I get on!