[rspec-users] Spec'ing ActionMailer

David Chelimsky dchelimsky at gmail.com
Sun Feb 4 16:47:55 EST 2007


On 2/4/07, David Chelimsky <dchelimsky at gmail.com> wrote:
> 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)
> }

I forgot to mention that you'll need this in setup/teardown when
interacting w/ mail:

setup do
  ActionMailer::Base.delivery_method = :test
  ActionMailer::Base.perform_deliveries = true
  ActionMailer::Base.deliveries = []
end

teardown
  ActionMailer::Base.deliveries.clear
end

This email support is from a port of assert_select, and that's how
assert_select works.

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