# Creating instance of ActionMailer for testing

**URL:** <https://www.ruby-forum.com/t/creating-instance-of-actionmailer-for-testing/155244>\
**Category:** Rails\
**Created:** [December 9, 2008, 8:46pm UTC](https://www.ruby-forum.com/t/creating-instance-of-actionmailer-for-testing/155244 "2008-12-09T20:46:11Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dmitry\_Ratnikov](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/dbc845/32.png) [@Dmitry\_Ratnikov](https://www.ruby-forum.com/u/Dmitry_Ratnikov)\
**Post date:** [December 9, 2008, 8:46pm UTC](https://www.ruby-forum.com/t/creating-instance-of-actionmailer-for-testing/155244/1 "2008-12-09T20:46:11Z")

</div>

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  
end  
end

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?

Thanks,  
Dmitry

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 @profile.name, so  
the test has to know that the template renders just the name and  
change if the template changes)

---

<div class="post-metadata">

**Author:** ![Dmitry\_Ratnikov](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/dbc845/32.png) [@Dmitry\_Ratnikov](https://www.ruby-forum.com/u/Dmitry_Ratnikov)\
**Post date:** [December 9, 2008, 10:53pm UTC](https://www.ruby-forum.com/t/creating-instance-of-actionmailer-for-testing/155244/2 "2008-12-09T22:53:18Z")

</div>

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)  
end

should “contain key pair :bar =\> @bar” do  
assert\_equal @bar, @body\_hash[:bar]  
end  
end

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.

Dmitry

---

<div class="post-metadata">

**Author:** ![Dmitry\_Ratnikov](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/dbc845/32.png) [@Dmitry\_Ratnikov](https://www.ruby-forum.com/u/Dmitry_Ratnikov)\
**Post date:** [December 9, 2008, 9:18pm UTC](https://www.ruby-forum.com/t/creating-instance-of-actionmailer-for-testing/155244/3 "2008-12-09T21:18:36Z")

</div>

Email templates change very rarely on my project, so I don’t mind the  
usual  
approach of matching the body against a few patterns. And, it’s easy to  
do.  
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 =\> "  
removed\_email\_address@domain.invalid")  
@applicant = stub(:full\_name =\> “john doe”, :user =\> @user)  
@assessment\_url = “[http://www.example.com](http://www.example.com)”  
@email = Mailer.create\_job\_application\_submitted(@applicant,  
@assessment\_url)  
end

it “addresses the email from the support address” do  
@email.from.should == [“removed\_email\_address@domain.invalid”]  
end

it “addresses the email to the given user” do  
@email.to.should == [@user.email\_address]  
end

it “sets the subject” do  
@email.subject.should == “#{@applicant.full\_name.titleize} - Job  
application submitted”  
end

it “includes the applicant name in the body” do  
@email.body.should match(/#{@applicant.full\_name.titleize}/)  
end

it “includes the applicant’s assessment link in the body” do  
@email.body.should match(/#{@assessment\_url}/)  
end

end

Hope that helps somehow.

Also, the Rails Guides site has some content on testing mailers:  
[rails.info](http://guides.rails.info/testing_rails_applications.html#_testing_your_mailers).

Regards,  
Craig
