[rspec-users] Spec'ing ActionMailer

s.ross cwdinfo at gmail.com
Sun Feb 4 16:14:08 EST 2007

Yes, this works in the Test::Unit framework, but the rSpec behavior  
specing is -- to me -- different in spirit. My scenario is less about  
testing whether the mailer should send mail than it is about whether  
the action should trigger an email and then what the email should  
contain. I settled on this hack:

   specify "should send a ping when a signup occurs" do
     post :signup, {"member"=>{
       "email_confirmation"=>"joe at schmoe.com",
       "email"=>"joe at schmoe.com"}, "projects"=>["3"]}

     response.should be_success
     email = ActionMailer::Base.deliveries[0]
     email.body.should include('joe at schmoe.com')
     email.body.should include(projects(:trace).name)
     email.body.should include('member/show')
     email.to.should include('webmaster at test.host')

The code works, but relies on me knowing something about how  
ActionMailer collects emails in test mode. My question is: Should my  
spec presume this much knowledge or is there a better way to  
accomplish it?


On Feb 4, 2007, at 11:56 AM, Craig Demyanovich wrote:

> On Feb 4, 2007, at 1:53 PM, s.ross wrote:
>> Good morning (Pacific Time). I have a controller action that, as a
>> side-effect, sends an email to an administrator. I want it to do
>> something like this:
>> specify "when someone successfully signs up, an email should be sent
>> to the administrator with the person's contact page" do
>>    post :signup, {...lots o' params}
>>    response should_be success
>>    # here's where I want to see whether email was sent. Of course,
>> the code is bogus.
>>    email.body.should have_tag(:p, :content => /page=/)
>> end
>> Is there some way to reach in and grab the message (what I've written
>> as "email" above) so I can test the various parameters such as the
>> "to" array and the email contents? I'm most interested in whether the
>> controller/mailer interaction is working properly. Also, can I use
>> the DOM select expectations or is it a simple matcher?
> On my first Rails project, I had to test whether a controller sent
> email when a job application was submitted. Fortunately, ActionMailer
> doesn't deliver email when running in a test environment. Rather, it
> records deliveries and makes them available via
> ActionMailer::Base.deliveries. I demonstrate this below. Note that
> the chapter on ActionMailer in AWDwR was very helpful to me, since it
> described a couple of ways to test sending email. Anyway, here's the
> code. Perhaps you can translate it into some specs.
> Craig
> require File.dirname(__FILE__) + '/../test_helper'
> require 'jobs_controller'
> # Re-raise errors caught by the controller.
> class JobsController; def rescue_action(e) raise e end; end
> class JobsControllerTest < Test::Unit::TestCase
>    fixtures #...
>    def setup
>      #...
>      @emails     = ActionMailer::Base.deliveries
>      @emails.clear
>    end
>    def test_submit_application
>      post :submit_application, :job_application => {
>        # lots of params
>      }
>      assert_response :success
>      assert_template 'submit_application'
>      assert_equal(2, @emails.size)
>      email = @emails.first
>      assert_match(/Confirm/, email.subject)
>      assert_equal('john at doe.com', email.to()[0])
>      email = @emails[1]
>      assert_match(/Resume received/, email.subject)
>      assert_equal('jobs at host.com', email.to()[0])
>    end
> end
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list