[rspec-users] Spec'ing ActionMailer

s.ross cwdinfo at gmail.com
Mon Feb 5 14:45:56 EST 2007


David/Craig--

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

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

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

   specify "d'oh! should have a non-empty recipient list" do
     ActionMailer::Base.deliveries.size.should be(4)
     ActionMailer::Base.deliveries.inspect
     ActionMailer::Base.deliveries.each do |email|
       email.to_addrs.should_not be_empty
     end
   end

   specify "first email should have a list item with the name of the  
first guy" do
     ActionMailer::Base.deliveries.first.body.should_include(members 
(:existing_user_1).first)
   end

   teardown do
     ActionMailer::Base.deliveries.clear
   end
end

Comments?


On Feb 5, 2007, at 11:22 AM, Craig Demyanovich wrote:

>
> On Feb 5, 2007, at 1:52 PM, s.ross wrote:
>
>> David--
>>
>> 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.
>
> Steve,
>
> 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")
>    end
>
>   def test_confirm
>     response = OrderMailer.create_confirm(@order)
>     assert_equal("Pragmatic Store Order Confirmation",  
> response.subject)
>     assert_equal("dave at pragprog.com", response.to[0])
>     assert_match(/Dear Dave Thomas/, response.body)
>    end
> end
>
> 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.
>
> Regards,
> Craig
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list