Reputation: 164
So I am trying to test an abstract class. According to what I have read, give an class named Foo
, I can do the following in RSpec and it won't leak in to other tests.
let(:test) do
Class.new(Foo) do
# Do things here
end
end
However I found that it does still leak, when I do Foo.subclasses
in another location (depending on spec execution order).
I also tried to define the class the normal way and delete it in an after block, e.g.
let(:test) do
class Test < Foo; end
Test
end
...
after do
Object.send(:remove_const, :Test)
end
But that also didn't seem to work. Foo.subclasses
still seemed to contain the anonymous class.
Upvotes: 1
Views: 528
Reputation: 6659
I did some investigations on how subclasses
work, and here's what I found (though not really an answer to your question)
subclasses
call internally descendants
(they both come from ActiveSupport) which calls ObjectSpace.each_object
If you read it's doc, it says
The ObjectSpace module contains a number of routines that interact with the garbage collection facility and allow you to traverse all living objects with an iterator.
It's not super clear. But AFAIU it iterates over all objects that the GC knows about.
So the reality is this: this class is not reachable unless you ask GC about it, then it can give you a reference to it. (It's kind of hacky if you ask me)
IMO you should not trust subclasses
on any production code. It seems unpredictable. Maybe, whatever you are trying to achieve with subclasses
, could be done in a different way? (But that's a topic for another SO question)
Upvotes: 1