Article

Disabling Observers in Tests

Posted  by Blake Watters.

PublicCategorized as Software Development and Near-Time.

Tagged with rails and ruby.

At Near-Time, our models have recently suffered an onslaught of observers that handle all sorts of wonderful stuff. Sometimes, however, those wonderful Observers can start to get in the way of my testing efforts by introducing all sorts of external dependencies and behavior that is quite outside of what I want to test. So tonight I took up the cause of writing a simple test helper that is capable of disabling a given set of Observers for the duration of a test. Here’s the code:

  def disable_observers(observers)
    @observers ||= []
    observers.each do |observer|
      next if @observers.include?(observer)
      instance_methods = {}
      [:after_create, :after_destroy, :after_save, :after_update, :after_validation, :after_validation_on_create, 
       :after_validation_on_update, :before_create, :before_destroy, :before_save, :before_update, :before_validation, 
       :before_validation_on_create, :before_validation_on_update].each do |callback|
         next unless observer.send(:method_defined?, callback)
         method = observer.send(:instance_method, callback)
         instance_methods[callback] = method
         observer.send(:remove_method, callback)
         observer.send(:define_method, callback) { true }
      end      
      @observers << [observer => instance_methods]
    end
  end

def restore_observers
  return true unless @observers
  @observers.each do |observers_info|      
    observers_info.each do |info|
      observer = info.keys.first
      instance_methods_info = info.values.first
      instance_methods_info.each_pair do |callback, method|
        observer.send(:remove_method, callback)
        observer.send(:define_method, callback, method)
      end
    end
  end
  @observers = nil
end

Usage:


class FooTest < Test::Unit::TestCase def setup disable_observers(SomeObserver, EntityObserver) end

def teardown
  restore_observers
end
end

UPDATE*: I missed some callbacks methods in my original post. The code now contains all available callbacks.


Arrow_down Hide comments

Powered by Strategy-NetsTerms of Services | Privacy Policy | Security Policy |