Benito Serna Tips and tools for Ruby on Rails developers

How to test that an email was sent on a system spec

July 2, 2021

If you want to test that an email was sent on a system spec in rails…

What you can do is to check the ActionMailer::Base.deliveries to see if the email that you want is there.

You can look for the mail with something like this:

mail = ActionMailer::Base.deliveries.find { |mail|
  mail.to.incude? "mary@example.com"
}

Maybe you can write a helper method to make the code a little more readable:

def find_mail_to(email)
  ActionMailer::Base.deliveries.find { |mail| mail.to.include?(email) }
end

And you can check if the subject is right with something like this:

expect(mail.subject).to eq "Super subject!"

A full example

Imagine that you are building an app to manage events, and you are writing a feature to invite guests to an event via email.

So, in your system spec you want to check that when you create an invitation the system will send the right email to the invited guest.

Then you can write something like this in your spec:

RSpec.describe "Event owner invites guest" do
  scenario "successfully" do
    event = create :event

    login_as event.owner

    visit event_path(event)

    create_invitation(name: "Mary", email: "mary@example.com")

    mail = find_mail_to "mary@example.com"

    expect(mail.subject).to eq "You have been invited to #{event.name}"
  end

  def create_invitation(name:, email:)
    click "Invite guest"
    fill_in "Name", with: name
    fill_in "Email", with: email
    click_on "Create invitation"
  end

  def find_mail_to(email)
    ActionMailer::Base.deliveries.find { |mail| mail.to.include?(email) }
  end
end

Related articles

Subscribe to get future posts via email

Here I try to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or all posts.