0x0b: Saving is a virtue, avarice is a vice

In functional tests a controller instance should not be reused: usually controller instances hold some state, that gets discarded in the normal Rails life cycle, and our tests must reflect that. Otherwise, tests can fail even if they shouldn’t, but even worse tests could succeed when they shouldn’t.

See this testcase:

require File.dirname(__FILE__) + '/../test_helper'

class DuuController  < ActionController::Base
  def index
    @test ||= params[:test]
    render :text => @test, :layout => false 
  end
end

class DontUseAControllerTwiceInATestcaseTest  < ActionController::TestCase
  def setup
    @controller = DuuController.new
    ...
  end

  def test_with_strange_results
    get :index, :test => "duu1"
    assert_equal("duu1", @response.body)

    get :index, :test => "duu2"
    assert_equal("duu1", @response.body)    # !!Watch this!!!
  end
end

This, of course, matches the Rails lifecycle of objects during an action: Rails creates a controller instance for each incoming request, and throws it away afterwards. This again matches the stateless behaviour of HTTP connections: each action response starts with a clean sheet. And wonderfully enough this ensures that all memory used by the response is cleaned up afterwards (unless you shoot yourself in our foot, of course, and if the ruby interpreter plays along nicely.)

If you need a series of simulated requests in a single test then you must recreate the @controller object from scratch:

  def test_duu2
    get :index, :test => "duu1"
    assert_equal("duu1", @response.body)

    @controller = DuuController.new
    
    get :index, :test => "duu2"
    assert_equal("duu2", @response.body)    # !!Watch this!!!
  end

To be honest I have no idea why rails best practices apparently recommend this. A simple change, and we could happily write

class SmarterTestingTest  < ActionController::TestCase
  testing :duu_controller
  ...
end

No setup needed, at least not the boilerplate part. Remember DRY?

Advertisements

One response to “0x0b: Saving is a virtue, avarice is a vice

  1. Pingback: 0×0c - 10+1 things I hate about rails « 1rad

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s