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.
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.
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
A cannot be autoloaded at that point (perhaps the autoloaders have not yet been set up).