I use Rails Wisper gem and I want to execute listener callback (which sends email) only during specific tests (where I test email sending). In other tests I don't want to send emails even if in production my callback would send them.
Is it possible with Wisper?
publisher (app/models/order.rb)
class Order < ActiveRecord::Base
include Wisper::Publisher
after_save do
publish(:order_after_save, self)
end
end
listener/observer (app/observers/mailer_order_observer.rb)
class MailerOrderObserver
def order_after_save order
if order.status_id_changed? && order.status.notify?
# send email
end
end
end
subscription (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
test (spec/observers/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
I the test above I want to execute MailerOrderObserver order_after_save callback, but not in any other tests (many "orders" are created and changed what normally would trigger email sending).
I use RSpec as testing framework and FactoryGirl.
Of course creating new Order instances with FactoryGirl triggers mailing, which is also not desired.
I found a solution (any better answer will be appreciated):
config.before(:suite)block so it won't receive any notifications during the tests.spec/spec_helper.rb
spec/observers/mailer_order_observer_spec.rb
This way
MailerOrderObserverreceives notifications from publisher only whenWisper.subscribe...is executed before the test.Note that it is convenient to use
let!(with exclamation mark) in order to instantiateorderbefore subscribing to the Wisper. This way only one publisher notification is received during test. Usingletinstead will cause two notifications: one aftercreate...and one caused byorder.save.