Rails Wisper пропускает обратный вызов слушателя

Я использую Rails Wisper gem и хочу выполнить обратный вызов слушателя (который отправляет электронную почту) только во время определенных тестов (где я тестирую отправку электронной почты). В других тестах я не хочу отправлять электронные письма, даже если в процессе производства мой обратный вызов отправит их.

Это возможно с Wisper?

издатель (app / models / order.rb)

class Order < ActiveRecord::Base
  include Wisper::Publisher

  after_save do
    publish(:order_after_save, self)
  end

end

слушатель / наблюдатель (приложение / наблюдатели / mailer_order_observer.rb)

class MailerOrderObserver

  def order_after_save order
    if order.status_id_changed? && order.status.notify?
      # send email
    end
  end
end

подписка (config / initializers / wisper.rb)

Rails.application.config.to_prepare do
  Wisper.clear if Rails.env.development? || Rails.env.test?
  # add observers
  Wisper.subscribe(MailerOrderObserver.new)
end

тест (spec / наблюдатели / mailer_order_observer_spec.rb)

require 'spec_helper'

describe MailerOrderObserver, type: :model do
  let (:order) { create(:order, :with_items) }

  it 'should send email' do
    order.status = create(:status_released)
    # emails are handled by external service, line below just triggers
    # sending
    expect(order.save).to eq(true)
  end
end

Я тест выше хочу выполнить MailerOrderObserverorder_after_save обратный вызов, но не в каких-либо других тестах (создается и изменяется много "заказов", что обычно вызывает отправку электронной почты).

Я использую RSpec в качестве основы тестирования и FactoryGirl.

Конечно создавая новые Order экземпляры с FactoryGirl запускают рассылку, что также нежелательно.

1 ответ

Я нашел решение (любой лучший ответ будет оценен):

  1. Отписать слушателя в вопросе в RSpec config.before(:suite) заблокировать, чтобы он не получал никаких уведомлений во время тестов.

спецификации /spec_helper.rb

RSpec.configure do |config|

  config.before(:suite) do
    # unsubscribe observer
    Rails.application.config.to_prepare do
      Wisper.unsubscribe(MailerOrderObserver.new)
    end
  end
end
  1. Подпишитесь на слушателя только для избранных тестов.

спецификации / наблюдателей /mailer_order_observer_spec.rb

require 'spec_helper'

describe MailerOrderObserver, type: :model do
  # ! prevents lazy loading
  let! (:order) { create(:order, :with_items) }

  describe '.order_after_save' do
    before do
      Wisper.subscribe(MailerOrderObserver.new)
    end

    it 'should send email' do
      order.status = create(:status_released)
      expect(order.save).to eq(true)
    end
  end
end

Сюда MailerOrderObserver получает уведомления от издателя только тогда, когда Wisper.subscribe... выполняется перед тестом.

Обратите внимание, что это удобно использовать let! (с восклицательным знаком), чтобы создать экземпляр order перед подпиской на Wisper. Таким образом, только одно уведомление издателя получено во время теста. С помощью let вместо этого вызовет два уведомления: одно после create... и один вызван order.save,

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