[rspec-users] Spec'ing ActionMailer
cdemyanovich at gmail.com
Mon Feb 5 19:02:26 EST 2007
On Feb 5, 2007, at 2:45 PM, s.ross wrote:
> Two tests are actually what I'm doing. I'm testing two separate
> mailers. The first is triggered as a side effect of an action. That
> mailer is inextricably intertwined with the controller, as it has to
> provide a URL to the page of someone who signed up, etc. I suppose I
> could mock the controller object, but does that really provide better
Isolating the controller and mailer as much as possible is the best
approach, IMHO. And, I don't think any mailer has to be bound tightly
to a controller. Here's what I'd do.
Specify each mailer in isolation, focusing on all the interesting
bits of the email messages that the mailers will create. For example:
context "An email for a new member" do
specify "includes the URL used at sign up" do
mail = MemberDigest.create_welcome(@member)
Then I'd mock/stub the one mailer and verify that the controller uses
it correctly. As a second option, I'd just let the controller use the
mailer and verify that I had one delivery; I wouldn't pick apart the
delivery, though, since I'd be comfortable that I'd specified the
mailer well enough already.
> The second mailer is, as mentioned, triggered from the command line
> and is being tested in a fashion similar to AWDROR's. Here is the
> (acckkk!) code I settled on, which IMO violates a lot of OO
> require File.dirname(__FILE__) + '/../spec_helper.rb'
> context "A MemberDigest" do
> fixtures :members
> setup do
> ActionMailer::Base.delivery_method = :test
> ActionMailer::Base.perform_deliveries = true
> ActionMailer::Base.deliveries = 
> MemberDigest.trigger_emails # invokes model method to send 4
> specify "d'oh! should have a non-empty recipient list" do
> ActionMailer::Base.deliveries.size.should be(4)
> ActionMailer::Base.deliveries.each do |email|
> email.to_addrs.should_not be_empty
> specify "first email should have a list item with the name of the
> first guy" do
> teardown do
Again, I'm tempted to specify the mailer in isolation and either
trust that delivery will happen if I ask for it or specify delivery
in isolation. Bear in mind that I might be missing something about
this example, as my experience with Rails is still somewhat limited.
> On Feb 5, 2007, at 11:22 AM, Craig Demyanovich wrote:
>> On Feb 5, 2007, at 1:52 PM, s.ross wrote:
>>> I still don't have this working (see my previous email with the
>>> pastie attached), but now have another ActionMailer/rSpec question.
>>> I'm spec'ing a different mailer model directly (instead of through
>>> the controller). It's meant to be invoked through script/runner,
>>> so I
>>> won't have a response object.
>> Your comments got me thinking about this again. First, there is the
>> behavior that you expect your controller to exhibit: that certain
>> actions send email. Second, there is the behavior that your
>> ActionMailer::Base derivative should exhibit: that it creates email
>> as you like. Furthermore, you write that you want to invoke an
>> ActionMailer::Base derivative via script/runner instead of or in
>> addition to a controller.
>> Therefore, you should specify their respective behaviors
>> independently of one another. I'm including a code snippet from
>> _Agile Web Development with Rails, 2nd ed._, that shows an example of
>> testing the ActionMailer::Base derivative by itself. I'm sure you can
>> translate the test to a spec.
>> require File.dirname(__FILE__) + '/../test_helper'
>> require 'order_mailer'
>> class OrderMailerTest < Test::Unit::TestCase
>> def setup
>> @order = Order.new(:name =>"Dave Thomas", :email =>
>> "dave at pragprog.com")
>> def test_confirm
>> response = OrderMailer.create_confirm(@order)
>> assert_equal("Pragmatic Store Order Confirmation",
>> assert_equal("dave at pragprog.com", response.to)
>> assert_match(/Dear Dave Thomas/, response.body)
>> Taking this approach will allow you to minimize the number of tests
>> that you write to prove that the controller behaves as it should.
>> Then, you can focus your attention on the ActionMailer::Base
>> derivative alone for all the things you want to verify about the
>> content of email. I hope this helps somehow.
>> rspec-users mailing list
>> rspec-users at rubyforge.org
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users