[rspec-users] Spec'ing ActionMailer

David Chelimsky dchelimsky at gmail.com
Sun Feb 4 16:35:05 EST 2007


Steve - are you using the RSpec trunk?

If you are, AND your email is html email, you can use this right now:

response.should send_email {
  with_tag("div", "joe at shmoe.com")
  with_tag("div", projects(:trace).name)
  with_tag("div", member/show)
}

There is no specific support yet for email headers, nor raw text,
though I can see now there is a need for that and will raise the
appropriate RFE.

David

On 2/4/07, s.ross <cwdinfo at gmail.com> wrote:
> 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",
>        "last"=>"Schmoe",
>        "first"=>"Joe",
>        "phone"=>"111-222-3333",
>        "working_with_agent"=>"0",
>        "preferred_contact_method"=>"email",
>        "agent_name"=>"",
>        "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')
>    end
> end
>
> 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?
>
> Steve
>
> 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
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list