Подтвердить что ты не робот

Как протестировать Rspec, если отправлено электронное письмо

Я бы хотел проверить, отправлено ли электронное письмо, если я вызову метод контроллера с помощью: post. Я буду использовать email_spec, поэтому я попробовал это здесь: http://rubydoc.info/gems/email_spec/1.2.1/file/README.rdoc#Testing_In_Isolation

Но это не сработает, потому что я передаю экземпляр объекта модели методу доставки, и экземпляр сохраняется до доставки.

Я попытался создать другой экземпляр объекта model-object, но тогда id не совпадает.

Мой метод-контроллер выглядит следующим образом:

def create

   @params = params[:reservation]

   @reservation = Reservation.new(@params)
   if @reservation.save
      ReservationMailer.confirm_email(@reservation).deliver
      redirect_to success_path
   else
      @title = "Reservation"
      render 'new'
   end

end

Есть ли у вас идея решить эту проблему?

4b9b3361

Ответ 1

Предполагая, что ваша тестовая среда настроена обычным способом (т.е. у вас есть config.action_mailer.delivery_method = :test), тогда отправленные электронные письма вставляются в глобальный массив ActionMailer::Base.deliveries как Mail::Message экземпляры. Вы можете прочитать это из своего тестового примера и убедиться, что сообщение электронной почты как ожидается. См. здесь.

Ответ 2

Настройте тестовую среду для накопления отправленных сообщений в ActionMailer::Base.deliveries.

# config/environments/test.rb
config.action_mailer.delivery_method = :test

Затем что-то вроде этого должно позволить вам проверить, что почта была отправлена.

# Sample parameters you would expect for POST #create.
def reservation_params
  { "reservation" => "Drinks for two at 8pm" }
end

describe MyController do
  describe "#create" do
    context "when a reservation is saved" do
      it "sends a confirmation email" do
        expect { post :create, reservation_params }.to change { ActionMailer::Base.deliveries.count }.by(1)
      end
    end
  end
end

Обратите внимание, что в моем примере используется синтаксис RSpec 3.

Ответ 3

Я знаю, что опаздываю на вечеринку с этим, но для будущих гуглеров...

Я думаю, что лучшее решение этой проблемы будет отвечать здесь

Ранее принятый ответ проверяет сам Mailer (внутри спецификации контроллера). Все, что вы должны тестировать здесь, это то, что Mailer получает сообщение о том, чтобы доставить что-то с правильными параметрами.

Затем вы можете проверить Mailer в другом месте, чтобы убедиться, что он правильно отвечает на эти параметры.

ReservationMailer.should_receive (: confirm_email).с (an_instance_of (резервирование))

Ответ 4

Для записи любому, кто использует rspec 3.4 и ActiveJob для отправки асинхронных сообщений электронной почты, вы можете проверить это с помощью

expect {
  post :create, params
}.to have_enqueued_job.on_queue('mailers')

Ответ 5

Это способ проверки того, что Mailer вызывается с правильными аргументами. Вы можете использовать этот код в спецификации функции, контроллера или почтовой программы:

delivery = double
expect(delivery).to receive(:deliver_now).with(no_args)

expect(ReservationMailer).to receive(:confirm_email)
  .with('reservation')
  .and_return(delivery)

Ответ 6

Чтобы добавить немного больше, убедитесь, что вы собираетесь отключить вызов, используя метод was_receive, который у вас есть тест интеграции в другом месте, проверяющий, что вы действительно вызываете метод правильно.

Я несколько раз бил, меняя метод, который был протестирован в другом месте с помощью функции should_receive, и тесты по-прежнему проходят, когда вызов метода был нарушен.

Если вы предпочитаете проверять результат, а не использовать should_receive, у shoulda есть хороший помощник, который работает следующим образом:

it { should have_sent_email.with_subject(/is spam$/) }

Документация по документации

Дополнительная информация об использовании совпадений с запятой с rSpec

Ответ 7

Если вы используете Capybara с электронной почтой [email protected] и отправили электронное письмо на [email protected], вы также можете использовать этот метод:

email = open_email('[email protected]')

И тогда вы можете проверить это следующим образом:

expect(email.subject).to eq('SUBJECT')
expect(email.to).to eq(['[email protected]'])