views:

366

answers:

2

I've got code that only needs to run on a certain version of ActiveRecord (a workaround for a bug on old AR libraries). This code tests the values of ActiveRecord::VERSION constants to see if it needs to be run.

Is there a way to mock out those constants in rspec so I can test that code path without relying on having the right ActiveRecord gem installed on the test machine?

+3  A: 

I ended up writing a helper method to let me override constants while executing a block of code:

def with_constants(constants, &block)
  constants.each do |constant, val|
    Object.const_set(constant, val)
  end

  block.call

  constants.each do |constant, val|
    Object.send(:remove_const, constant)
  end
end

After putting this code in your spec_helper.rb file, it can be used as follows:

with_constants :RAILS_ROOT => "bar", :RAILS_ENV => "test" do
  code goes here ...
end

Hope this works for you.

Drew Olson
Works like a charm, thanks.
Toms Mikoss
A: 

Drew Olson, I took your idea and made a few modifications to add scoping:

class Object
  def self.with_constants(constants, &block)
    old_constants = Hash.new
    constants.each do |constant, val|
      old_constants[constant] = const_get(constant)
      silence_stderr{ const_set(constant, val) }
    end

    block.call

    old_constants.each do |constant, val|
      silence_stderr{ const_set(constant, val) }
    end
  end
end

After putting this code at specs/support/with_constants.rb file, it can be used as follows:

MyModel.with_constants :MAX_RESULT => 2, :MIN_RESULT => 1 do
  code goes here ...
end
peleteiro