Heckle your ActiveRecord objects

|

I was recently watching Geoffrey Grosenbach's third PeepCode episode focused on rSpec: rSpec Controllers and Tools.

At one point during the screencast, while working with Heckle, Geoffrey mentioned that it is easiest to run heckle against a single instance method of your own making due to the fact that all objects that are subclassed from ActiveRecord::Base have all the AR methods globbed in. No need to heckle Rails itself, eh? By the way, if you are unfamiliar with Heckle, Kevin Clark has a great overview.

The thing is, I want to heckle all my methods at once. A little A - B and a rake task is all it took.

  
    namespace :spec do
      desc "Heckle a class"
      task :heckle => :environment do
        unless ENV.include?("model")
          raise "usage: rake test:heckle model=User"
        end

        #The user is allowed to test a single method
        #with User#activate! or similar
        inputs = ENV["model"].split("#")

        model = inputs[0].capitalize
        test_prefix = "#{model.downcase}"
        klass = Object.const_get("#{model}")

        #First check to see if user provided
        #an instance method name. ex: User#activate!
        methods = [inputs[1]] if inputs.size == 2

        #If the user only passed in a model name,
        #we need to get the instance methods that
        #are not part of ActiveRecord::Base
        methods ||= klass.instance_methods - ActiveRecord::Base.instance_methods

        methods.each do |method|
          cmd = "spec spec -H #{model}##{method}"
          system(cmd)
        end
      end  
    end
  

If you would like to heckle all the methods for an object (we'll user a User object as an example), run the following:

  
    > rake spec:heckle model=User
  

You can heckle a single method like so:

  
    > rake spec:heckle model=User#encrypt
  

You can download this task as well as it's Test::Unit counterpart here: heckle.rake

The rake tasks have beend DRYed up a little so that we can run most of the same code regardless of whether you are using rpsec or Test::Unit.

Enjoy!