Как проверить почтовый ящик для сброса пароля с помощью Capybara и Minitest в Rails 5
Я использую гем Clearance в Rails вместе с Capybara и Minitest и не могу понять, как протестировать почтовую программу сброса пароля. Я не пытаюсь протестировать гем Clearance, который уже хорошо протестирован, но я хотел бы провести интеграционный тест высокого уровня, чтобы убедиться, что ожидаемый пользовательский опыт не нарушается, и включает в себя почтовую программу.
Вот тест, который я не могу выполнить (/integration/password_reset_test.rb):
require 'test_helper'
class PasswordResetTest < ActionDispatch::IntegrationTest
def setup
ActionMailer::Base.deliveries.clear
@user = create(:user)
end
test "User can reset their password" do
visit "/login"
assert page.current_path == "/login"
click_link "Forgot password?"
assert page.current_path == "/passwords/new"
assert_selector "h1", text: "Reset your password"
fill_in("Email", :with => @user.email)
click_button "Reset your password"
assert page.current_path == "/passwords"
assert_selector "h1", text: "Your password reset email is on the way."
# This is where I'm stuck
# Would like to test that the correct email was sent by checking
# basic content in the email and then simulate a user clicking
# the password reset link and then updating their password.
end
end
Как вы на самом деле проверяете, что письмо было отправлено правильно, и есть ли способ имитировать капибару, щелкнув ссылку сброса пароля в письме, а затем заполнив форму для сброса пароля?
Я тоже это попробовал, но эта строка провалилась, поэтому я явно что-то не так делаю:
assert_equal 1, ActionMailer::Base.deliveries.size
Я могу проверить вручную, выбрав ссылку электронной почты для сброса пароля из журналов сервера, поэтому эта функция работает правильно.
Все примеры, которые я могу найти в Интернете, предполагают, что вы используете Rspec, но ничего для Minitest. Я также попытался использовать гем capybara -email, но у него не было примеров Minitest, и я тоже не смог заставить его работать.
Для справки: Gemfile test_helper.rb
1 ответ
Для того, что вы хотите сделать capybara-email
хороший выбор Чтобы настроить его, вы должны включить его в ActionDispatch::IntegrationTest
или в отдельный тестовый класс, где это необходимо (в вашем текущем случае - PasswordResetTest
). Скорее всего, вам также необходимо настроить ActiveJob для выполнения заданий, когда они ставятся в очередь, а не откладывают их (в противном случае электронные письма фактически не будут отправлены). Одним из способов сделать это является включение ActiveJob::TestHelper
а затем с помощью perform_enqueued_jobs
Метод это предусмотрено. Это приводит к чему-то вроде
require 'test_helper'
class PasswordResetTest < ActionDispatch::IntegrationTest
include Capybara::Email::DSL
include ActiveJob::TestHelper
def setup
clear_emails
@user = create(:user)
end
test "User can reset their password" do
perform_enqueued_jobs do
visit "/login"
assert_current_path("/login")
click_link "Forgot password?"
assert_current_path("/passwords/new")
assert_selector "h1", text: "Reset your password"
fill_in("Email", :with => @user.email)
click_button "Reset your password"
assert_current_path("/passwords")
assert_selector "h1", text: "Your password reset email is on the way."
end
open_email(@user.email)
assert_content(current_email, 'blah blah')
current_email.click_link('Reset Password')
assert_current_path(reset_password_path)
... # fill out form with new password, etc.
end
end
Обратите внимание на использование assert_current_path
скорее, чем assert page.current_path...
- Как правило, вы предпочитаете первый, так как последний не имеет поведения ожидания / повторной попытки и может привести к ошибочным тестам. Также обратите внимание, что написание тестов с жестким кодом в именах путей приводит к кошмару, если вы когда-нибудь захотите изменить имена путей, поэтому вам лучше было бы писать свои коды, используя вместо этого помощники по маршрутам
assert_current_path(login_path)
и т.п.