Тестирование отложенных почтовых программ в методе Rails - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть метод rails, который позволяет пользователю отправить отзыв и контрагента, он отправляет электронное письмо с использованием отложенных заданий.

def update_review
  @review.add_review_content(review_params)
  ReviewMailer.delay.review_posted(@review.product_owner, params[:id])
end

И я пытаюсь добавить тест rspec длячтобы проверить, правильно ли доставлен почтовый ящик и кому.Задержанные задания запускаются сразу после их создания в test, потому что я хочу, чтобы другие задания, например задание, обновляли общий рейтинг владельцев продукта, чтобы были немедленно завершены.

Так что электронная почта действительно отправляется, но как я могу добавитьтест для него?

РЕДАКТИРОВАТЬ: Добавление текущих тестов

Мои текущие тесты:

describe 'PUT #update the review' do

  let(:attr) do
    { rating: 3.0, raw_review: 'Some example review here' }
   end

   before(:each) do
     @review = FactoryBot.create :review
     put :update, id: @review.id, review: attr
   end

   it 'creates a job' do
     ActiveJob::Base.queue_adapter = :test
     expect {
       AdminMailer.review_posted(@coach, @review.id).deliver_later
     }.to have_enqueued_job
   end 

   it { should respond_with 200 }

end

Это действительно проверяет, что почтовик работает правильно, но я хочу проверить, чтоон также корректно запускается в потоке методов.

1 Ответ

0 голосов
/ 11 декабря 2018

Похоже, что вы хотите, чтобы метод update_review ставил в очередь задание на отправку правильного письма нужному получателю.Вот более простой способ сделать это:

describe 'PUT #update the review' do
  let(:params) { { rating: rating, raw_review: raw_review } }
  let(:rating) { 3.0 }
  let(:raw_review) { 'Some example review here' }
  let(:review) { FactoryBot.create(:review) }
  let(:delayed_review_mailer) { instance_double(ReviewMailer) } 

  before do
    # assuming this is how the controller finds the review...
    allow(Review).to receive(:find).and_return(review)

    # mock the method chain that enqueues the job to send the email
    allow(ReviewMailer).to receive(:delay).and_return(delayed_review_mailer)
    allow(delayed_review_mailer).to receive(:review_posted)

    put :update, id: review.id review: params
  end

  it 'adds the review content to the review' do
    review.reload
    expect(review.rating).to eq(rating) 
    expect(review.raw_review).to eq(raw_review)
  end

  it 'sends a delayed email' do
    expect(ReviewMailer).to have_received(:delay)
  end

  it 'sends a review posted email to the product owner' do
    expect(delayed_review_mailer)
      .to have_received(:review_posted)
      .with(review.product_owner, review.id)
  end
end

Причина, по которой я предпочитаю этот подход, состоит в том, что а) это можно сделать, не затрагивая базу данных вообще (путем замены фабрики на экземпляр double), и b) он не пытается тестировать части Rails, которые уже были протестированы людьми, создавшими Rails, такими как ActiveJob и ActionMailer.Вы можете доверять собственным модульным тестам Rails для этих классов.

...