ActionMailer testing with rspec
30,261
How to test ActionMailer with RSpec
- works for Rails 3 and 4
- this information has been taken from a good tutorial
Assuming the following Notifier
mailer and User
model:
class Notifier < ActionMailer::Base
default from: '[email protected]'
def instructions(user)
@name = user.name
@confirmation_url = confirmation_url(user)
mail to: user.email, subject: 'Instructions'
end
end
class User
def send_instructions
Notifier.instructions(self).deliver
end
end
And the following test configuration:
# config/environments/test.rb
AppName::Application.configure do
config.action_mailer.delivery_method = :test
end
These specs should get you what you want:
# spec/models/user_spec.rb
require 'spec_helper'
describe User do
let(:user) { User.make }
it "sends an email" do
expect { user.send_instructions }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
# spec/mailers/notifier_spec.rb
require 'spec_helper'
describe Notifier do
describe 'instructions' do
let(:user) { mock_model User, name: 'Lucas', email: '[email protected]' }
let(:mail) { Notifier.instructions(user) }
it 'renders the subject' do
expect(mail.subject).to eql('Instructions')
end
it 'renders the receiver email' do
expect(mail.to).to eql([user.email])
end
it 'renders the sender email' do
expect(mail.from).to eql(['[email protected]'])
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
Props to Lucas Caton for the original blog post on this topic.
Author by
Dinkaran Ilango
Updated on October 16, 2020Comments
-
Dinkaran Ilango over 3 years
I am developing a Rails 4 application which involves sending / receiving emails. For example, I send emails during user registration, user comment, and other events in the app.
I have created all emails using the action
mailer
, and I usedrspec
andshoulda
for testing. I need to test if the mails are received correctly to the proper users. I don't know how to test the behavior.Please show me how to test an
ActionMailer
usingshoulda
andrspec
. -
Phillipp about 9 yearsBut that would not catch any problems if you, let's say catch an exception from the User.send_instructions and send yourself an email with the exception. You just test if any e-mail is sent, not your specific one.
-
janechii about 8 years@Phillipp made a good point, and if you'd like to test specific mail(s),
ActionMailer::Base.deliveries
is an array ofMail::Message
objects. Refer to Mail::Message API. -
Aesthetic almost 7 yearsFor those who wonder why
mock_model
doesn't work: stackoverflow.com/a/24060582/2899410 -
glinda93 almost 3 yearsFor those who want to test
deliver_later
, check this post too: stackoverflow.com/a/42987726/11792577