Como testar mailers no Rails com RSpec

Como testar mailers no Rails com RSpec

O módulo ActionMailer foi refeito no Rails 3 e os mailers ganharam um subdiretório próprio (dentro do app/) desde então.

Esse post vai demonstrar como testá-los no Rails using RSpec. Supondo que temos um mailer como esse:

class Notifier < ActionMailer::Base
  default from: 'noreply@company.com'

  def instructions(user)
    @name = user.name
    @confirmation_url = confirmation_url(user)
    mail to: user.email, subject: 'Instructions'
  end
end

Para enviar um email através de um método da classe User:

class User
  def send_instructions
    Notifier.instructions(self).deliver_now
  end
end

Antes de testá-lo, garanta que o arquivo config/environments/test.rb esteja configurado assim:

Rails.application.configure do
  config.action_mailer.delivery_method = :test
end

Isso garante que os e-mails não serão realmente enviados, e sim armazenamos no array ActionMailer::Base.deliveries.

Verificado isso, basta criar os testes:

spec/models/user_spec.rb

require 'spec_helper'

RSpec.describe User, type: :model do
  subject { create :user }

  it 'sends an email' do
    expect { subject.send_instructions }
      .to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end

spec/mailers/notifier_spec.rb

require 'spec_helper'

RSpec.describe Notifier, type: :mailer do
  describe 'instructions' do
    let(:user) { mock_model User, name: 'Lucas', email: 'lucas@email.com' }
    let(:mail) { described_class.instructions(user).deliver_now }

    it 'renders the subject' do
      expect(mail.subject).to eq('Instructions')
    end

    it 'renders the receiver email' do
      expect(mail.to).to eq([user.email])
    end

    it 'renders the sender email' do
      expect(mail.from).to eq(['noreply@company.com'])
    end

    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end

    it 'assigns @confirmation_url' do
      expect(mail.body.encoded)
        .to match("http://aplication_url/#{user.id}/confirmation")
    end
  end
end

Rails possibilita criar testes bastante compreensivos para mailers. Happy coding!

Comments are closed.