-
Notifications
You must be signed in to change notification settings - Fork 154
Test only selected listeners with RSpec
How to prevent listener from being called in every test but make it active for selected ones.
EXAMPLE
publisher (app/models/order.rb)
class Order < ActiveRecord::Base
include Wisper::Publisher
after_save do
publish(:order_after_save, self)
end
endlistener/observer (app/observers/mailer_order_observer.rb)
class MailerOrderObserver
def order_after_save order
# some actions after saving the order
# which we don't want to execute during all tests just in selected blocks
# e.g. sending an email
end
endsubscription (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)
endspec/spec_helper.rb
RSpec.configure do |config|
config.before(:suite) do
# unsubscribe observer before tests
to_remove = Wisper::GlobalListeners.listeners.select do |l|
l.instance_of?(MailerOrderObserver) # get listeners of selected class
end
to_remove.each do |remove|
Wisper::GlobalListeners.unsubscribe(remove)
end
end
endtest (spec/observers/mailer_order_observer_spec.rb)
require 'spec_helper'
describe MailerOrderObserver, type: :model do
# ! prevents lazy loading
let! (:order) { create(:order) }
let (:listener) { MailerOrderObserver.new }
describe '.order_after_save' do
# thanks to that create(:order) will not trigger listener callback method
before { Wisper.subscribe(listener) }
before { Wisper.unsubscribe(listener) } # not available even in 2.0.0rc1 (use master branch head?)
it 'should send email' do
expect(order.save).to eq(true)
end
it 'should send email another test' do
expect(order.save).to eq(true)
end
end
endThis way MailerOrderObserver receives notifications from publisher only when Wisper.subscribe... is executed before the test.
Note that it is convenient to use let! (with exclamation mark) in order to instantiate order before subscribing to the Wisper. This way only one publisher notification is received during test. Using let instead will cause two notifications: one after create... and one caused by order.save.
Need to ask a question? Please ask on StackOverflow tagging the question with wisper.
Found a bug? Please report it on the Issue tracker.