Benito Serna
Ruby, Rails, TDD...

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

If you want to test that an email was sent on a feature 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 feature 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.feature "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