Forum: Ruby on Rails Creating instance of ActionMailer for testing

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
A211797acb8ea1910014a4144176453a?d=identicon&s=25 Dmitry Ratnikov (Guest)
on 2008-12-09 20:46
(Received via mailing list)
Hi all,
 I am writing an action mailer test and am trying to snatch contents
of the @body hash provided for the template for testing. Specifically,
my plan is to do something like:

FooMailer.class_eval do
  attr_accessor :original_body
  def render_message method, body
    self.original_body = body
    super method, body

and then test that a FooMailer instance has its original_body setup
correctly (together with to, from and other headers).

However, I noticed that ActionMailer::Base goes out of its way to
prevent instantiating mailer objects. Why does it do that?


PS I realize that usual approach is just use pattern matching for the
resulting TMail body. However such method seems to strongly couple the
test to the email body template (e.g. I may setup the body[:profile]
but the email resulting body may only contain the, so
the test has to know that the template renders just the name and
change if the template changes)
B14575f0ca69f10938fdd67e7156e0e1?d=identicon&s=25 Craig Demyanovich (Guest)
on 2008-12-09 21:18
(Received via mailing list)
Email templates change very rarely on my project, so I don't mind the
approach of matching the body against a few patterns. And, it's easy to
Anyway, here's an example spec of a mailer on my current project:

describe Mailer, "job application submitted" do

  before(:each) do
    @user = stub(:full_name => "Jane Roe", :email_address => "")
    @applicant = stub(:full_name => "john doe", :user => @user)
    @assessment_url = ""
    @email = Mailer.create_job_application_submitted(@applicant,

  it "addresses the email from the support address" do
    @email.from.should == [""]

  it "addresses the email to the given user" do == [@user.email_address]

  it "sets the subject" do
    @email.subject.should == "#{@applicant.full_name.titleize} - Job
application submitted"

  it "includes the applicant name in the body" do
    @email.body.should match(/#{@applicant.full_name.titleize}/)

  it "includes the applicant's assessment link in the body" do
    @email.body.should match(/#{@assessment_url}/)


Hope that helps somehow.

Also, the Rails Guides site has some content on testing mailers:

A211797acb8ea1910014a4144176453a?d=identicon&s=25 Dmitry Ratnikov (Guest)
on 2008-12-09 22:53
(Received via mailing list)
Thanks for the reply! Your solution works, but it is pretty much same
as just doing assert_matches.
 After some thinking I realized that I can just stub out the
render_message of the ActionMailer::Base class:

 context "Email body hash" do
   setup do
     @bar = Bar.create!
     FooMailer.any_instance.stubs(:render_message).with { |template,
body| @body_hash = body}.returns(:email_body)
     @email = FooMailler.create_send_foo(@bar)

   should "contain key pair :bar => @bar" do
     assert_equal @bar, @body_hash[:bar]

 And that seems to do the trick.
 I am still quite curious as to why ActionMailer::Base is so set
against having instances, but at least it works.

This topic is locked and can not be replied to.