There are different practices, that I know, to test that an email was sent in Rails…
ActionMailer::Base.deliveries
All of them have pros and cons and will help you test different things.
That is why I think that is good to understand all of them because it will help you decide which method is better case by case.
It will be similar to what you will do on a feature/capybara spec.
You will check the ActionMailer::Base.deliveries
to see if the email that you want is there.
RSpec.describe Event, "#create_invitation" do
it "sends the invitation email" do
event = create :event
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 find_mail_to(email)
ActionMailer::Base.deliveries.find { |mail|
mail.to.include?(email)
}
end
end
Using rspec, you can expect that an object will receive the right method that will actually deliver the mail.
RSpec.describe Event, "#send_invitation_emails" do
it "sends the email for all invitations" do
event = create :event
invitation1 = create :invitation, event: event
invitation2 = create :invitation, event: event
expect(invitation1).to receive(:send_email)
expect(invitation2).to receive(:send_email)
event.send_invitation_emails
end
end
Using rspec, you can allow your mailer to receive new
with the right
attributes and then return an object that will receive the method that actually
delivers the mail.
RSpec.describe Invitation, "#send_email" do
it "sends the new_invitation email" do
invitation = build :invitation
mail = double("Mail")
allow(EventMailer).to receive(:new_invitation).with(invitation).and_return(mail)
expect(mail).to receive(:deliver_later)
invitation.send_email
end
end
As you can see not all tests will test exactly the same thing. And most of the time you won’t need all of them.
If you are struggling deciding which test to write, I recommend you to start with the feature/capybara spec.
Then if you fill that you need to test something at the unit/micro level, you can try this methods in order, but just moving to the next method only if you really feel that is necesary.
So, you can start with the first method, then if you need more confidence you can try the second, and finally the third method if you really think that is necessary.
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.