Ryan Carmelo Briones

mostly harmless

Testing ActionMailer renders template October 23, 2008

Today I was pair programming with Josh Schairbaum on my new job at Braintree when we came across an interesting problem. Today's task: provide translations for emails being sent out based on a database setting. Seems easy enough. Like a good pair the first thing we do is open up our test file and start up autotest. Hold on. ActionMailers look like a "model" and act like a controller. How do we test this?

We did a fair bit of searching the internets and found almost nothing. To be fair, the keywords for searching for this aren't very specific. We'll give it the old college try. First we tried to [flex]mock our what to testing that the proper template got called. That was a no go. Lets take a look at the source code. Looks like there's a template attribute, lets try testing that. Wait, how do you get at an ActionMailer object? MyMailerClass.create_mailer returns a TMail object. How about MyMailerClass.new, that should get us somewhere. It sure did: "undefined method 'template' for nil:NilClass". MyMailerClass.new is returning nil? This is weird. new is getting called in other places in ActionMailer::Base, why can't we do the same.

Then, a stroke of mad sciencry hits me, "What does MyMailerClass.send(:new) return?" An MyMailerClass object! Amazing! Though it together in a test and you've got:

Hope this helps someone!