Potential gotcha with test setup in Rails 2.0

Wednesday, December 05

UPDATE 2: This is now fixed in Rails trunk.

UPDATE 1: Josh Peek has already created a patch that prevents this gotcha. Read the patch and give it a +1 on the Rails Trac if you’re so inclined: http://dev.rubyonrails.org/ticket/10382.

Rails 2.0 introduces a new (better) way to create your functional test cases. Instead of subclassing Test::Unit::TestCase directly, you can now subclass ActionController::TestCase, which will take care of the setting up the request/response environment for you. Here’s what a Rails 2.0 functional test might look like:

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

class AuctionsControllerTest < ActionController::TestCase
  def test_should_require_login_for_create
    assert_login_required 'create'
  end
  # ...
end

Now, suppose you’re using the setup method to prepare a few things before each of your test methods run. You may remember that prior to this change, each functional test needed to define its own setup method in which it created a controller instance, and instances of TestRequest and TestResponse. Well, it still does. Only this setup method is moved to the new superclass, saving you the typing.

And therein lies the gotcha: if you go ahead and create your own setup method not realizing that you’ve inherited one, you’ll clobber the one defined in the superclass. So, when you’re defining your own setup method, remember to call the original one using super:

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

class AuctionsControllerTest < ActionController::TestCase
  def setup
    super
    @current_user = login_as(:amy)
  end

  def test_should_require_login_for_create
    assert_login_required 'create'
  end
  # ...
end

Hopefully this will save you the 15 minutes I spent trying to figure out why this wasn’t working.

Comments

Leave a response

  1. Josh PeekDecember 05, 2007 @ 04:28 PM

    I think we can patch this so you don’t have to call super. The same technique that is used to setup fixtures can be used here. I think its just doing some alias_method_chain hackery.

  2. Josh PeekDecember 05, 2007 @ 04:42 PM

    Well, its done :)

    Please +1 me.

    http://dev.rubyonrails.org/ticket/10382

  3. Jeffrey HardyDecember 05, 2007 @ 04:54 PM

    @Josh: Nice. That was fast. Faster than writing this blog post!

  4. James GolickDecember 07, 2007 @ 12:05 PM

    The same problem exists in the ActionMailer::TestCase class.

    Here’s my patch, using the same technique: http://dev.rubyonrails.org/ticket/10406