Rails, Firefox, Anime, Mac
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.
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
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 [...]
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 [...]
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!
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
Tecker.LOG » Blog Archive » ???????Cheah Chu Yeow?Rails??
June 4th, 2008 at 12am
[...] Rails 2.0 a feature a day serials [...]
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 [...]
Controller testing ?? Rails 2.2 « Tik’s Blog
January 5th, 2009 at 9pm
[...] ??????????????????????????????? declare setup ???????????? ActionController::TestCase ??????? @controller, @request, ??? @response ????????????????????????? Rails 2.0 [...]