Why test Rails emails with MailHog?
Rails ships with ActionMailer previews and :test delivery mode — but neither sends real SMTP traffic. Previews show individual templates; the test adapter captures mailer calls in memory. Neither catches encoding bugs, broken MIME structure, or spam triggers.
MailHog captures the actual SMTP envelope — the same bytes a real mail server would receive. You see rendered HTML, full headers, spam scoring, and attachment handling in a proper inbox UI.
Quickstart: Rails configuration
Update your development environment config:
# config/environments/development.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV.fetch("SMTP_HOST", "smtp.mailhog.site"),
port: ENV.fetch("SMTP_PORT", 2525).to_i,
user_name: ENV["SMTP_USER"],
password: ENV["SMTP_PASS"],
authentication: :plain,
enable_starttls_auto: false,
}Send a test email from the console
$ rails console > UserMailer.welcome(User.first).deliver_now # Check MailHog dashboard — email appears instantly ✅
Testing with RSpec
For integration tests that need to verify actual email delivery, point your test environment at MailHog and use the API to assert:
# spec/features/password_reset_spec.rb
require "rails_helper"
require "net/http"
RSpec.describe "Password reset flow", type: :feature do
it "sends a reset email" do
user = create(:user, email: "test@example.com")
post forgot_password_path, params: { email: user.email }
# Query MailHog API
uri = URI("#{MAILHOG_URL}/api/v1/inbox/#{INBOX_ID}/messages")
uri.query = URI.encode_www_form(to: "test@example.com")
res = Net::HTTP.get_response(uri)
emails = JSON.parse(res.body)["data"]
expect(emails).not_to be_empty
expect(emails.first["subject"]).to include("Reset")
end
endCommon pitfalls with ActionMailer
- Setting
enable_starttls_auto: truewhen MailHog doesn't use TLS on port 2525 - Forgetting to set
config.action_mailer.raise_delivery_errors = true— silent failures hide SMTP issues - Using
deliver_laterwithout running Sidekiq/ActiveJob — emails queue but never send - Not testing multipart emails (HTML + text) — many Rails mailers only generate one format