Как проверить почтовый ящик для сброса пароля с помощью 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)

и т.п.

Другие вопросы по тегам