Modifying a ruby class doesn't work as expected when running Spork

Go To StackoverFlow.com

1

I have a plain Ruby class in my Rails app that I'm reopening in a test environment. It basically looks like

class A
  def get_dependency
    B
  end
  ... some other methods ...
end

And in my test environment in cucumber (in a file loaded from features/env.rb) (and a similar place for rspec) I do

class A
  def get_dependency
    MockedB
  end
end

This works fine in normal runs, but when I have Spork running, it fails strangely. Class A's get_dependency method is overwritten properly, but all its other public methods are now missing. Any ideas?

I'm assuming this is related to load order somehow, but I didn't get any changes when I moved the require for my file out of the preload section of Spork.

2012-04-04 19:43
by ced


0

This isn't a great answer, but it's a workaround. Instead of reopening the class I just modified a singleton instance. The code is basically the same, except I added an instance method on A:

class A
  def instance
    @@instance ||= A.new
  end
end

Then in my test code I modified the instance

instance = A.instance
def instance.get_dependency
  MockedB
end

And I just had to ensure that my actual code was always calling A.instance instead of A.new.

2012-04-05 13:54
by ced


0

One possible scenario is that A is set to get autoloaded, but when you define the override for it in your cucumber environment, you do so before it has been autoloaded; since A now exists, it will never get autoloaded.

A possible solution, which invokes the autoloader before overriding the method is this:

A.class_exec do
  def get_dependency
    MockedB
  end
end

It will raise a ConstMissing if A cannot be autoloaded at that point (perhaps the autoloaders have not yet been set up).

2012-04-17 18:21
by yaauie
Ads