DRY in your functional and ActionMailer tests – Rails 2.0 a feature a day #7

In: Open Source|Ruby|Ruby on Rails

27 Dec 2007

That’s right, Don’t Repeat Yourself in your functional and ActionMailer tests. If you’re a Test::Unit user, this will probably look familiar to you when writing Rails functional tests (for your controllers):

class PostsControllerTest < Test::Unit::TestCase
  def setup
    @controller = PostsController.new
    @request    = ActionController::TestRequest.new
    @response   = ActionController::TestResponse.new
  end

  def test_should_not_explode
    # Invariably sexy test code.
  end
end

You’d probably have noticed how setup always sets the @controller, @request and @response instance variables in all your controller tests. In Rails 2.0, you can instead subclass ActionController::TestCase (in turn a subclass of Test::Unit::TestCase) in your test cases and avoid repeating the instance variable assignments.

class PostsControllerTest < ActionController::TestCase
  # No need to define setup.

  def test_should_not_explode
    # Invariably sexy test code.
  end
end

Isn’t that much better?

Watch out for a gotcha though, when you actually do need to define a setup method (like when you need to setup several other things before your tests run), as Jeffrey Allan Hardy reports. The issue has been resolved on edge Rails. If you’re not using edge Rails, you should remember to always call super in your setup method should you define one:

class PostsControllerTest < ActionController::TestCase
  def setup
    super
    @user = users(:konata)
  end

  def test_should_not_explode
    # Invariably sexy test code.
  end
end

A similar subclass of Test::Unit, ActionMailer::TestCase is available for your ActionMailer unit tests as well. That means you can replace this:

class UserMailerTest < Test::Unit::TestCase
  include ActionMailer::Quoting

  def setup
    ActionMailer::Base.delivery_method = :test
    ActionMailer::Base.perform_deliveries = true
    ActionMailer::Base.deliveries = []

    @expected = TMail::Mail.new
    @expected.set_content_type "text", "plain", { "charset" => "utf-8" }
    @expected.mime_version = '1.0'
  end

  def test_signup
    # Test code.
  end
end

with this:

class UserMailerTest < ActionMailer::TestCase
  def test_signup
    # Test code.
  end
end

For the geeks among you, check out the related changeset.

About the contributor, Michael Koziarski

Michael Koziarski, better know as nzkoz, is a long-time Rails core committer. Michael has done a signficant amount of work improving the performance of ActiveRecord for Rails 2.0 so we have him to thank for a good portion of the optimization work done on ActiveRecord. He also keeps a fairly new personal blog.

7 Responses to DRY in your functional and ActionMailer tests – Rails 2.0 a feature a day #7

Avatar

What’s new on edge Rails - the pilot - redemption in a blog

January 2nd, 2008 at 7pm

[…] new TestCase subclasses (ActionController::TestCase, ActionMailer::TestCase) introduced in Rails 2 have a gotcha. This has […]

Avatar

Space Babies » Blog Archive » Sweeter unit tests in Rails 2.0

March 11th, 2008 at 7pm

[…] only just now discovered a sweet new feature of Rails 2.0. Unit and functional tests have gotten a lot sweeter. I can now subclass ActionController::TestCase and do away with all the setup cruft that used to be […]

Avatar

joost baaij

March 11th, 2008 at 7pm

Thanks, I missed this nugget!

However, in my testcases that subclass from ActionController::TestCase the setup method doesn’t seem to be executed at all. Debug output isn’t shown, the super method isn’t called. nada!

Avatar

Thong Kuah

April 7th, 2008 at 9am

@joost,

This is a bug in Rails, where setup is not being called, if you are using rails 2.0.2. This was fixed in revision 8442 (one revision after rails 2.0.2 was released). See http://dev.rubyonrails.org/ticket/10568

Basically, I think you might want to rake rake rails:freeze:edge REVISION=8442

Avatar

Tecker.LOG » Blog Archive » ???????Cheah Chu Yeow?Rails??

June 4th, 2008 at 12am

[…] Rails 2.0 a feature a day serials […]

Avatar

Tecker.LOG » Blog Archive » ????ActionMailer?????DRY(????????)?????Rails 2.0?? #7(??)

June 4th, 2008 at 8pm

[…] ???DRY in your functional and ActionMailer tests – Rails 2.0 a feature a day #7 […]

Avatar

Controller testing ?? Rails 2.2 « Tik’s Blog

January 5th, 2009 at 9pm

[…] ??????????????????????????????? declare setup ???????????? ActionController::TestCase ??????? @controller, @request, ??? @response ????????????????????????? Rails 2.0 […]