Rails - Cómo probar ActionMailer envió un correo electrónico específico en tests
Actualmente en mis pruebas hago algo como esto para probar si un correo electrónico está en cola para ser enviado
assert_difference('ActionMailer::Base.deliveries.size', 1) do
get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
Pero si una acción del controlador puede enviar dos correos electrónicos diferentes, es decir, uno al usuario si el registro va bien o una notificación al administrador si algo salió mal, ¿cómo puedo probar cuál realmente se envió? El código anterior pasaría de todos modos.
6 answers
Cuando se usa el ActionMailer durante las pruebas, todos los correos se colocan en una gran matriz llamada deliveries
. Lo que básicamente está haciendo (y es suficiente en su mayoría) es comprobar si los correos electrónicos están presentes en la matriz.
Pero si desea comprobar específicamente para un cierto correo electrónico, usted tiene que saber lo que realmente se almacena en la matriz. Afortunadamente, los correos electrónicos se almacenan, por lo que puede iterar a través de la matriz y verificar cada correo electrónico.
Vea ActionMailer:: Base para ver qué configuración hay métodos disponibles, que puede usar para determinar qué correos electrónicos están presentes en la matriz. Algunos de los métodos más adecuados para su caso probablemente son
-
recipients
: Toma una o más direcciones de correo electrónico. Estas direcciones son donde su correo electrónico será entregado a. Establece el encabezado A:. -
subject
: El asunto de tu correo electrónico. Establece el encabezado Subject:.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-14 16:09:00
A partir de rails 3 ActionMailer:: Base.deliveries es una matriz de Mail:: Message. De la documentación de mail:
# mail['from'] = '[email protected]'
# mail[:to] = '[email protected]'
# mail.subject 'This is a test email'
# mail.body = 'This is a body'
#
# mail.to_s #=> "From: [email protected]\r\nTo: you@...
A partir de eso, debería ser fácil probar sus correos en una integración
mail = ActionMailer::Base.deliveries.last
assert_equal '[email protected]', mail['from'].to_s
assert_equal '[email protected]', mail['to'].to_s
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-18 19:11:13
Usando la sintaxis actual de Rspec, terminé usando lo siguiente:
last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['[email protected]']
expect(last_email.subject).to have_content 'Welcome'
El contexto de mi prueba fue una especificación de características en la que quería asegurarme de que se enviara un correo electrónico de bienvenida a un usuario después de registrarse.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-20 20:54:09
El marco de prueba shoulda tiene un excelente ayudante que le permite afirmar ciertas condiciones sobre un correo electrónico que se envió. Sí, podrías hacerlo tú mismo con ActionMailer.entregas, pero shoulda lo hace todo un pequeño bloque ordenado
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-14 16:30:40
Un poco tarde, pero puede ayudar a otros:
Puedes usar Email-spec, una colección de emparejadores Rspec/Minitest y pasos de pepino.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-16 06:41:24
Aquí está la mejor manera que he encontrado para hacerlo.
1) Incluye el complemento callbacks de action mailer como este:
script/plugin install git://github.com/AnthonyCaliendo/action_mailer_callbacks.git
Realmente no uso las características principales del plugin, pero proporciona la buena funcionalidad de ser capaz de averiguar qué método se utilizó para enviar un correo electrónico.
2) Ahora puede poner algunos métodos en su test_helper.rb como este:
def assert_sent(method_name)
assert sent_num_times(method_name) > 0
end
def assert_not_sent(method_name)
assert sent_num_times(method_name) == 0
end
def assert_sent_once(method_name)
assert sent_num_times(method_name) == 1
end
def sent_num_times(method_name)
count = 0
@emails.each do |email|
count += 1 if method_name == email.instance_variable_get("@method_name")
end
count
end
3) Ahora puedes escribir pruebas dulces como esta:
require 'test_helper'
class MailingTest < ActionController::IntegrationTest
def setup
@emails = ActionMailer::Base.deliveries
@emails.clear
end
test "should send a mailing" do
assert_difference "Mailing.count", 1 do
feeds(:feed1).generate_mailing
end
assert_sent_once "broadcast"
assert_not_sent "failed_mailing"
end
end
Aquí "broadcast" y " mailing_failed" son los nombres de los métodos en mi clase ActionMailer::Base. Estos son los que normalmente usas llamando a Mailer.deliver_broadcast(some_data)
o Mailer.deliver_failed_mailing(some_data)
etc. ¡Eso es!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-12 03:23:27