Enabling/disabling observers for testing 4
If you use ActiveRecord observers in your application and are concerned about the isolation of your model unit tests, you probably want some way to disable/enable observers. Unfortunately, Rails doesn't provide an easy way to do this. So, here's some code I threw together a while ago to do just that.
module ObserverTestHelperMethods
def observer_instances
ActiveRecord::Base.observers.collect do |observer|
observer_klass = \
if observer.respond_to?(:to_sym)
observer.to_s.camelize.constantize
elsif observer.respond_to?(:instance)
observer
end
observer_klass.instance
end
end
def observed_classes(observer=nil)
observed = Set.new
(observer.nil? ? observer_instances : [observer]).each do |observer|
observed += (observer.send(:observed_classes) + observer.send(:observed_subclasses))
end
observed
end
def observed_classes_and_their_observers
observers_by_observed_class = {}
observer_instances.each do |observer|
observed_classes(observer).each do |observed_class|
observers_by_observed_class[observed_class] ||= Set.new
observers_by_observed_class[observed_class] << observer
end
end
observers_by_observed_class
end
def disable_observers(options={})
except = options[:except]
observed_classes_and_their_observers.each do |observed_class, observers|
observers.each do |observer|
unless observer.class == except
observed_class.delete_observer(observer)
end
end
end
end
def enable_observers(options={})
except = options[:except]
observer_instances.each do |observer|
unless observer.class == except
observed_classes(observer).each do |observed_class|
observer.send :add_observer!, observed_class
end
end
end
end
end
Include this in a Test::Unit::TestCase or 'include' in your RSpec configuration, whatever rocks your boat. Here's a stupid example:
class SomethingCoolTest < Test::Unit::TestCase
include ObserverTestHelperMethods
def setup
disable_observers
end
def teardown
enable_observers
end
def test_without_observers
# ...
end
end
When you go to test the behavior of the observer itself, simply disable/enable like the following to disable/enable all observers except the one you're testing:
class DispassionateObserverTest < Test::Unit::TestCase
include ObserverTestHelperMethods
def setup
disable_observers :except => DispassionateObserver
end
def teardown
enable_observers :except => DispassionateObserver
end
def test_without_observers_except_dispassionate_observer
# ...
end
end

I've done some testing around observers recently and we came up with a simple way of preventing observers from interfering with our tests - it's not as flexible as your solution but I'm not sure it needs to be that flexible.
Given a model Foo, and an observer FooObserver, in our Foo tests, in the setup, we would stub the Foo#notify method (we are using mocha):
We would then test our Observers separately:
This allows us to test our objects and their observers in isolation; in general you can rely on Rails to do the right thing and make sure your observers get called in the right place although you could also write some integration/functional tests to confirm this.
Crystal shoes fairy tale Cinderella has made a perfect love story.christian louboutin slingback Orsay As a result,every woman dreams of being Cinderella wonderdful.In the real world,it's the designer who created a sophisticated high-heeled shoes many of their gifts and light hands,and countless women and to help achieve their dreams.High-profile christian louboutin is one of the outstanding one them.Louboutin boots Many women are crazy,his shoes.christian louboutin Jane's independence,he has expanded his personal charm shoe designer's reputation.
http://www.lighteveryday.com Welcome to LightEveryDay.com. Our company offer led lights,led strip, led ribbon, led car light, led power supply, led
controller.High quality LED Strip with low price.
This allows us to analyze our things and their experts in isolation; in common you can depend on Tracks to do the right factor and create sure your experts get known as in the right position although you could also create some integration/functional assessments to validate this dissertation-writing-help.org .