An enhanced assert_did_not_send_email for Shoulda

Posted by Nathaniel on March 13th, 2009 15:20

Shoulda is an excellent bit of icing for writing and maintaining your Ruby Test::Unit tests. The library is written and maintained by the great guys over at Thoughtbot. Shoulda comes with dozens of macros (which run several several specific tests in one line of code), custom assertions, and general features allowing you to write your tests in a far more easily understood format.

Now, just some of those custom assertions that I find myself using quite a bit are the assert_sent_email and assert_did_not_send_email. Actually, I pretty much use them all and then some. Anyway, getting back to the email assertions, the two don’t act the same out of the box. assert_sent_email can take a block which allows you to test for specific email criteria. assert_did_not_send_email, however, does not.

The following little snippet of code comes in quite handy if you are in a situation where you want to test that one person receives an email while another does not.

class Test::Unit::TestCase
  
  def assert_did_not_send_email
    if block_given?
      msg = "One or more sent emails matched your criteria.\n"
      emails = ::ActionMailer::Base.deliveries
      matching_emails = emails.select {|email| yield email }
      assert matching_emails.empty?, msg
    else
      msg = "Sent #{::ActionMailer::Base.deliveries.size} emails.\n"
      ::ActionMailer::Base.deliveries.each { |m| msg << " ‘#{m.subject}’ sent to #{m.to.to_sentence}\n ”p">}
      assert ::ActionMailer::Base.deliveries.empty?, msg
    end
  end
  
end
 

view raw This Gist brought to you by GitHub.

So, for example, you could: assert_did_not_send_email { |email| email.subject == 'Bad' }

Update: A patch and ticket have been created in the lighthouse project.

Be the first to comment…

Post a comment

[Textile formatting enabled]

Nathaniel Bibler

Christopher Green

RailsConf 2009