Zulhilmi Zainudin
Zulhilmi Zainudin

Reputation: 9365

How to test ActionMailer delivery_method in RSpec?

I have 2 delivery_methods, switchable using a environment variable like so:

config.action_mailer.delivery_method = :mailjet

OR

config.action_mailer.delivery_method = :smtp

How do test the delivery_method in RSpec tests?

Upvotes: 0

Views: 2131

Answers (2)

sonna
sonna

Reputation: 620

Do you mean, testing whether or not the setting is set?

require "rails_helper"

RSpec.describe "Rails application configuration" do
  it "set the delivery_method to test" do
    expect(Rails.application.config.action_mailer.delivery_method).to eql :test
    expect(ActionMailer::Base.delivery_method).to eql :test
  end
end

Or it is using the something like SMTP library is used underneath it all?

require "rails_helper"
require "net/smtp"

RSpec.describe "Mail is sent via Net::SMTP" do
  class MockSMTP
    def self.deliveries
      @@deliveries
    end

    def initialize
      @@deliveries = []
    end

    def sendmail(mail, from, to)
      @@deliveries << { mail: mail, from: from, to: to }
      'OK'
    end

    def start(*args)
      if block_given?
        return yield(self)
      else
        return self
      end
    end
  end

  class Net::SMTP
    def self.new(*args)
      MockSMTP.new
    end
  end

  class ExampleMailer < ActionMailer::Base
    def hello
      mail(to: "smtp_to", from: "smtp_from", body: "test")
    end
  end

  it "delivers mail via smtp" do
    ExampleMailer.delivery_method = :smtp
    mail = ExampleMailer.hello.deliver_now

    expect(MockSMTP.deliveries.first[:mail]).to eq mail.encoded
    expect(MockSMTP.deliveries.first[:from]).to eq 'smtp_from'
    expect(MockSMTP.deliveries.first[:to]).to eq %w(smtp_to)
  end
end

Like Max's answer, you really cannot truly the mailer delivery_method since it is a service that may or may not exist in your test environment and thus is often stubbed out; e.g.

 # config/environments/test.rb
 # Tell Action Mailer not to deliver emails to the real world.
 # The :test delivery method accumulates sent emails in the
 # ActionMailer::Base.deliveries array.
 config.action_mailer.delivery_method = :test

Upvotes: 1

max
max

Reputation: 102443

You don't. You don't really test configuration specifics in BDD or TDD as that is per environment and just generally a bad idea.

Rather the mailer in the test environment is set to just add emails to a spool so that you can expect/assert that emails have been sent.

  # config/environments/test.rb
  # Tell Action Mailer not to deliver emails to the real world.
  # The :test delivery method accumulates sent emails in the
  # ActionMailer::Base.deliveries array.
  config.action_mailer.delivery_method = :test

What is usually done instead is manually testing the email configuration in production. You can do this from the console or if you do it often create a rake task.

Upvotes: 0

Related Questions