Как проверить с Rspec, если письмо доставлено - PullRequest
29 голосов
/ 02 сентября 2011

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

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

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

Мой метод контроллера выглядит так:

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

У вас есть идеи, чтобы решить эту проблему?

Ответы [ 8 ]

53 голосов
/ 02 сентября 2011

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

20 голосов
/ 17 октября 2014

Сконфигурируйте свою тестовую среду для накопления отправленных писем в 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.

18 голосов
/ 16 апреля 2012

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

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

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

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

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

4 голосов
/ 29 июня 2016

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

expect {
  post :create, params
}.to have_enqueued_job.on_queue('mailers')
2 голосов
/ 20 августа 2015

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

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

expect(ReservationMailer).to receive(:confirm_email)
  .with('reservation')
  .and_return(delivery)
1 голос
/ 10 ноября 2017

Если вы используете Capybara с Capybara Email , и вы отправили электронное письмо на test@example.com, вы также можете использовать этот метод:

email = open_email('test@example.com')

И тогда вы можете проверить это так:

expect(email.subject).to eq('SUBJECT')
expect(email.to).to eq(['test@example.com'])
1 голос
/ 01 ноября 2012

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

У меня естьНесколько раз менял метод, который тестировался в другом месте с помощью must_receive, и тесты по-прежнему проходили, когда вызов метода был прерван.

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

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

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

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

0 голосов
/ 14 ноября 2016

Попробуйте email-spec

describe "POST /signup (#signup)" do
  it "should deliver the signup email" do
    # expect
    expect(UserMailer).to(receive(:deliver_signup).with("email@example.com", "Jimmy Bean"))
    # when
    post :signup, "Email" => "email@example.com", "Name" => "Jimmy Bean"
  end
end

больше примеров здесь: https://github.com/email-spec/email-spec#testing-in-isolation

...