Skip to content

Instantly share code, notes, and snippets.

@bcardarella
Created April 13, 2010 17:01
Show Gist options
  • Save bcardarella/364832 to your computer and use it in GitHub Desktop.
Save bcardarella/364832 to your computer and use it in GitHub Desktop.
Rspec ActiveRecord callback matchers
# Usage:
#
# describe Klass do
# it { should have_callback(:do_something).on(:before_save) }
# it { should have_callback(:make_change).on(:after_create) }
# it { should_not have_callback(:make_change).on(:before_save) }
# end
#
# class Klass < ActiveRecord::Base
# before_save :do_something
# after_create :make_change
# end
module Shoulda
module ActiveRecord
module CallbackMatcher
def have_callback(method)
HaveCallbackMatcher.new(method)
end
class HaveCallbackMatcher
attr_accessor :method, :callback_type, :callbacks
def initialize(method)
self.method = method.to_sym
end
def on(callback_type)
self.callback_type = callback_type
self
end
def matches?(subject)
@subject = subject.class
get_callbacks
if callbacks
return is_callback_method?
else
return false
end
end
def description
"has #{callback_type.to_s.gsub('_', ' ').capitalize} Callback method :#{method}"
end
def failure_message_for_should
"\n#{callback_type.to_s.gsub('_', ' ').capitalize} Callback method failure\nExpected: '#{method}'\n Got: nil"
end
def failure_message_for_should_not
"\n#{callback_type.to_s.gsub('_', ' ').capitalize} Callback method failure\nExpected: nil\n Got: '#{method}'"
end
private
def is_callback_method?
callbacks.detect { |callback| callback.method == method }
end
def get_callbacks
self.callbacks = @subject.instance_variable_get("@#{callback_type}_callbacks")
end
end
end
end
end
Spec::Runner.configure do |config|
config.include(Shoulda::ActiveRecord::CallbackMatcher)
end
@cscairns
Copy link

I could not get this to work in latest version of Rspec and Rails 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment