Rails-Jak testować ActionMailer wysłany konkretny e-mail w testach
Obecnie w moich testach robię coś takiego, aby sprawdzić, czy e-mail jest w kolejce do wysłania
assert_difference('ActionMailer::Base.deliveries.size', 1) do
get :create_from_spreedly, {:user_id => @logged_in_user.id}
end
Ale jeśli ja akcja kontrolera może wysłać dwa różne e-maile, tj. jeden do użytkownika, jeśli rejestracja pójdzie dobrze lub powiadomienie do admina, jeśli coś poszło nie tak - jak mogę sprawdzić, który z nich rzeczywiście został wysłany. Powyższy kod przejdzie niezależnie.
6 answers
Podczas korzystania z ActionMailer podczas testów, wszystkie wiadomości są umieszczane w dużej tablicy o nazwie deliveries
. To, co w zasadzie robisz (i jest wystarczające głównie), to sprawdzanie, czy e-maile są obecne w tablicy.
Ale jeśli chcesz dokładnie sprawdzić, czy nie ma określonej wiadomości e-mail, musisz wiedzieć, co jest faktycznie przechowywane w tablicy. Na szczęście same e-maile są przechowywane, dzięki czemu można iterację za pośrednictwem tablicy i sprawdzić każdy e-mail.
Zobacz ActionMailer::Base aby zobaczyć jaką konfigurację dostępne są metody, których można użyć do określenia, jakie wiadomości e-mail są obecne w tablicy. Niektóre z najbardziej odpowiednich metod dla Twojego przypadku to
-
recipients
: pobiera jeden lub więcej adresów e-mail. Te adresy są adresami, na które zostanie dostarczony twój e-mail. Ustawia nagłówek na:. -
subject
: temat twojego maila. Ustawia temat: nagłówek.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-14 16:09:00
Od rails 3 ActionMailer:: Base.delivery to tablica Mail:: Message ' s. From the mail documentation:
# 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@...
Od tego powinno być łatwo przetestować pocztę w integracji
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/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-18 19:11:13
Używając bieżącej składni Rspec, skończyłem używając następującej:
last_email = ActionMailer::Base.deliveries.last
expect(last_email.to).to eq ['[email protected]']
expect(last_email.subject).to have_content 'Welcome'
Kontekstem mojego testu była Specyfikacja funkcji, w której chciałem upewnić się, że wiadomość powitalna zostanie wysłana do użytkownika po zarejestrowaniu się.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 20:54:09
Framework testowy shoulda posiada doskonały helper, który pozwala na spełnienie pewnych warunków dotyczących wysłanej wiadomości e-mail. Tak, możesz to zrobić sam z ActionMailer.dostawy, ale powinno sprawić, że wszystko będzie jednym schludnym małym blokiem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-14 16:30:40
Trochę za późno, ale może pomóc innym:
Możesz użyć Email-spec, kolekcji matcherów Rspec/Minitest i kroków ogórkowych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-16 06:41:24
Oto najlepszy sposób, jaki znalazłem.
1) Dołącz action mailer callbacks plugin taki jak ten:
script/plugin install git://github.com/AnthonyCaliendo/action_mailer_callbacks.git
Naprawdę nie używam głównych funkcji wtyczki, ale zapewnia miłą funkcjonalność bycia w stanie dowiedzieć się, Która metoda została użyta do wysłania wiadomości e-mail.
2) Teraz możesz umieścić kilka metod w swoim test_helper.RB jak to:
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) Teraz możesz pisać takie słodkie testy:
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
Tutaj "broadcast" i " mailing_failed" są nazwami metod w mojej klasie Base ActionMailer::. Są to te, których zwykle używasz, wywołując Mailer.deliver_broadcast(some_data)
lub Mailer.deliver_failed_mailing(some_data)
itp. To jest to!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-12 03:23:27