Testing the Phoenix Elixir Mailer - Swoosh
Automated tests are an integral part of the software development lifecycle. They help us sleep at night, so that an update will not break the system. I don't think anyone would fancy working under stress on a weekend because of a bug they shipped on Friday evening,
While many write tests for complicated functions and behaviours, I often find people skip mailers. While I have done this myself, you should at least be able to test critical and time-sensitive emails.
Here is a simple example of how you can test your Phoenix Mailers.
Background
I am assuming the following:
- You are on an Elixir Phoenix code base
- You have configured Oban for job processing
- You have configured Swoosh as the mailer
- Your mailers are utilizing Oban jobs for delivering mail
Given that these assumptions are valid, this solution should work fine for you.
The Configuration
You'll need to set up Swoosh in the test environment like that. You may need to customize the mailer to your needs, but the following is the bare minimum for this post.
# lib/jdeen/mailer.ex
defmodule JDeen.Mailer do
use Swoosh.Mailer, otp_app: :sample
end
# config/test.exs
config :jdeen, JDeen.Mailer,
adapter: Swoosh.Adapters.Test
The Test
Assume you have to send a notification to a customer about
defmodule JDeen.Notifiers.NewInvoiceNotification do
@moduledoc false
use JDeen.DataCase, async: true
import Swoosh.TestAssertions
setup do
customer = JDeen.ConsumerFixtures.customer()
invoice =
JDeen.BillingFixtures.invoice(%{customer_id: customer_id})
%{
customer: customer,
invoice: invoice
}
end
test "sends the new invoice email with a link to the PDF download", %{
invoice: invoice
} do
job = %Oban.Job{args: %{"inovice_id" => invoice.id}}
JDeen.Notifiers.NewInvoiceNotification.perform(job)
assert_email_sent(fn email ->
assert email.text_body =~ customer.first_name
assert email.text_body =~ invoice.id
assert email.text_body =~ JDeen.Financial.format_currency(invoice.amount_cents, invoice.amount_currency)
assert email.text_body =~ JDeen.Billing.url(invoice, :pdf)
end)
end
end
As you can see, I am manually triggering the Oban job, which in turn would enqueue the mail. Then we can use assert_email_sent
. If you are expecting multiple emails to be sent, there is assert_emails_sent
. But this is just the test for this particular mailer.
References
Conclusion
Swoosh and Phoenix make it easy to test the mailer. If you are using CoPilot like me, it would have highlighted some weird code. I hope this helped you in your journey.
About the Author
Ziyan Junaideen -
Ziyan is an expert Ruby on Rails web developer with 8 years of experience specializing in SaaS applications. He spends his free time he writes blogs, drawing on his iPad, shoots photos.