I’ve just started using Observers in a Rails application I’m creating and found out that in order to have them picked up by rails you have to manually register the Observers within your environment.rb file, like so:

config.active_record.observers = :my_observer

I like to have as much coverage for any code I write in Rails, such as associations I’ve created, validation rules etc. I’m not testing the validation itself (Rails’ tests have that covered) what I’m testing is that I’ve actually applied the validation rule.

So I figured that I should do the same for the Observers which should be registered. I couldn’t find any references to anyone else doing this so after a little bit of digging I’ve come up with the following approach for use with RSpec:

matchers/observer_matchers.rb :

module Matchers
 module ObserverMatchers

  #
  # Used to check that an observer has been registered
  #
  class BeRegistered

   def initialize(observer_name)
    @observer_name = observer_name
   end

   def matches?(observers)
    @observers = observers
    @observers.include?(@observer_name)
   end

   def failure_message
    "expected observer with name of '#{@observer_name}' to be registered but wasn't"
   end

   def negative_failure_message
    "expected observer with name of '#{@observer_name}' not to be registered but was"
   end
  end

  #
  # Usage:
  #
  # ActiveRecord::Base.observers.should be_registered(:user_observer)
  def be_registered(*args)
   BeRegistered.new(*args)
  end

 end
end

models/user\_observer\_spec.rb

require File.dirname(__FILE__) + '/../spec_helper'

describe UserObserver do

 it "should be registered with the application" do
  ActiveRecord::Base.observers.should be_registered(:user_observer)
 end

 ...
end

It really is quite simple, but feel free to use the matcher if you want. Consider it released under BSD licence, no guarantees etc.