ActionMailer, Named Routes and Testing
I’ve immersed myself in Ruby and Rails for the last several weeks, working on a project I hope to complete in the next month or so. The other day, I created a new mailer to send a welcome message when a user registers with the site. I’d done a mailer before and written a unit test for it, and was surprised to see the following when I wrote a unit test for the new one:
1) Error:
test_welcome(UserAccountMailerTest):
ActionView::TemplateError: confirm_user_url failed to generate from {:controller=>"users", :email_address_id=>"1", :secret=>nil, :action=>"confirm"}, expected: {:controller=>"users", :action=>"confirm"}, diff: {:email_address_id=>"1", :secret=>nil}
It looks like ActionMailer isn’t happy when a mail template makes use of named routes when run inside the test framework, but that doesn’t make any sense. Here is the route, from routes.rb:
map.confirm_user "users/confirm/:email_address_id/:secret",
:controller => "users",
:action => "confirm",
:requirements => { :email_address_id => /\d+/,
:secret => /\d+/ }
The error seems to say that the routing framework is not parsing my route correctly, and fails to see that :email_address_id and :secret are both requirements for the route (“expected:” specifically excludes those two parameters).
This is one of those times where the error message didn’t help as much as I hope it would. It turns out that the entire problem is because “secret” is a new column, and I hadn’t added it to my fixtures yet. Fixing that fixes the problem, and my test passes.
Usually, the net is amazingly wise and I can find either an answer or a hint in the right direction after a few searches. This time, I had to rely on a “hey, wait a second…” moment.