Testando ActionMailer “deliver_later” com rspec

Eu queria testar o envio de algumas informações de perfil por e-mail. O motivo foi que eu mudei do processamento em linha para o processamento em segundo plano via ActiveJobs.

Como estamos em um ambiente de teste, não queremos enviar e-mails, então definimos o método de entrega test.rbpara :test:

config.action_mailer.delivery_method = :test

Primeiro eu tive que fazer include ActiveJob::TestHelperno meu teste de recursos. Isso fornece vários métodos para testar filas.

Para ter um ambiente de teste limpo, limpei primeiro todos os trabalhos enfileirados para evitar conflitos entre os testes.

before { clear_enqueued_jobs }

O teste:

scenario "a user sends his profile to a conusltant" do
sign_in_as
(user)

visit main_app
.new_send_profile_path

# Ensure user can not fill in an invalid email
fill_in
"Consultant E-Mail", with: "abc"

# No job is enqued, user has to fill in a correct email
expect
{ click_button "Send profile"}.to change { enqueued_jobs.size }.by(0)

fill_in
"Consultant E-Mail", with: "hans.muster@awesome-consulting.com"

expect
{ click_button "Send profile" }.to change { enqueued_jobs.size }.by(1)

mail
= perform_enqueued_jobs { ActionMailer::DeliveryJob.perform_now(*enqueued_jobs.first[:args]) }

expect
(ProfileMailer.deliveries.count).to eq 1

expect
(mail.subject).to have_content "Awesome survey"
end

A parte crucial era realizar o trabalho enfileirado para obter um e-mail adequado. O truque é realizar o trabalho manualmente:

mail = perform_enqueued_jobs { ActionMailer::DeliveryJob.perform_now(*enqueued_jobs.first[:args]) }

Isso está fornecendo o objeto de correio e a matriz de entregas como quando você envia inline.