В настоящее время в моих тестах я делаю что-то вроде этого, чтобы протестировать, если электронное письмо ставится в очередь, чтобы быть отправленным
assert_difference('ActionMailer::Base.deliveries.size', 1) do
get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
но если я, действие контроллера может послать два различных электронных письма т.е. одно пользователю, если подписываются, иду прекрасный или уведомление администратору, если что-то пошло не так, как надо - как я могу протестировать, какой на самом деле был отправлен. Код выше передал бы независимо.
При использовании ActionMailer во время тестов все почты помещаются в большой массив вызван поставками
. То, что вы в основном делаете (и достаточно в основном) проверяют, присутствуют ли электронные письма в массиве.
Но если вы хотите конкретно проверить определенное письмо, вы должны знать, что на самом деле сохраняется в массиве. К счастью, сами электронные письма хранятся, при этом вы сможете перейти через массив и проверять каждое электронное письмо.
См. ActionMailer :: Base Чтобы увидеть, какие методы конфигурации доступны, которые вы можете использовать, чтобы определить, какие электронные письма присутствуют в массиве. Некоторые из наиболее подходящих методов для вашего дела, вероятно, являются
получателями
: принимает один или несколько адресов электронной почты. Эти адреса находятся в том, где ваше электронное письмо будет доставлено. Устанавливает to: заголовок. Тема
: предмет вашей электронной почты. Устанавливает тему: заголовок. Test Framework HEPA имеет отличный помощник, который позволяет вам утверждать определенные условия о отправленном электронном письме. Да, вы могли бы сделать это самостоятельно с помощью ActionMailer.deeliveries, но должен сделать все один аккуратный маленький блок
Вот лучший способ, который я нашел для этого.
1) Включите плагин action mailer callbacks следующим образом:
script/plugin install git://github.com/AnthonyCaliendo/action_mailer_callbacks.git
Я не использую основные возможности плагина, но он предоставляет хорошую функциональность, позволяющую выяснить, какой метод был использован для отправки письма.
2) Теперь вы можете поместить некоторые методы в ваш test_helper.rb, как это:
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) Теперь вы можете написать милые тесты, как это:
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
Здесь "broadcast" и "mailing_failed" - это имена методов в моем классе ActionMailer::Base. Именно их вы обычно используете, вызывая Mailer.deliver_broadcast(some_data)
или Mailer.deliver_failed_mailing(some_data)
и т.д. Вот и все!
По состоянию на rails 3 ActionMailer :: Base.deliveries - это массив Mail :: Message. Из документации по почте :
# mail['from'] = 'mikel@test.lindsaar.net'
# mail[:to] = 'you@test.lindsaar.net'
# mail.subject 'This is a test email'
# mail.body = 'This is a body'
#
# mail.to_s #=> "From: mikel@test.lindsaar.net\r\nTo: you@...
Отсюда должно быть легко проверить вашу почту в интеграции
mail = ActionMailer::Base.deliveries.last
assert_equal 'mikel@test.lindsaar.net', mail['from'].to_s
assert_equal 'you@test.lindsaar.net', mail['to'].to_s