Rails - How do you test ActionMailer sent a specific email in tests

后端 未结 7 2040
面向向阳花
面向向阳花 2020-12-23 12:58

Currently in my tests I do something like this to test if an email is queued to be sent

assert_difference(\'ActionMailer::Base.deliveries.size\', 1) do              


        
7条回答
  •  孤城傲影
    2020-12-23 13:13

    As of 2020 (Rails 6 era, probably introduced earlier) you can do the following: (using a SystemTest example) TL;DR: use assert_emails from ActionMailer::TestHelper and ActionMailer::Base.deliveries.last to access the mail itself.

    require "application_system_test_case"
    require 'test_helper'
    require 'action_mailer/test_helper'
    
    class ContactTest < ApplicationSystemTestCase
      include ActionMailer::TestHelper
    
      test "Send mail via contact form on landing page" do
        visit root_url
    
        fill_in "Message", with: 'message text'
    
        # Asserting a mail is sent
        assert_emails 1 do
          click_on "Send"
        end
    
        # Asserting stuff within that mail
        last_email  = ActionMailer::Base.deliveries.last
    
        assert_equal ['whatever'], last_email.reply_to
        assert_equal "contact", last_email.subject
        assert_match /Mail from someone/, last_email.body.to_s
      end
    end
    

    Official doc:

    • ActionMailer Guide/Testing
    • Testing Guide/ActionMailer

    Note Instead of manually checking the content of the mail as in the system test above, you can also test whether a specific mailer action was used, like this:

    assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
    

    And some other handy assertion, see https://api.rubyonrails.org/v6.0.3.2/classes/ActionMailer/TestHelper.html#method-i-assert_emails .

提交回复
热议问题