如何阻止 RSpec 匿名 class 泄漏?

How to stop RSpec anonymous class leaking?

所以我正在尝试测试一个摘要 class。根据我的阅读,给一个名为Foo的class,我可以在RSpec中进行以下操作并且不会泄漏到其他测试中。

let(:test) do
  Class.new(Foo) do
    # Do things here
  end
end

然而,当我在另一个位置(取决于规范执行顺序)执行 Foo.subclasses 时,我发现它仍然会泄漏。

我还尝试以正常方式定义 class 并在后块中将其删除,例如

let(:test) do
  class Test < Foo; end
  Test
end
...

after do
  Object.send(:remove_const, :Test)
end

但这似乎也没有用。 Foo.subclasses 似乎仍然包含匿名 class。

我对 subclasses 的工作原理进行了一些调查,以下是我的发现(虽然不是您问题的真正答案)

subclasses 内部调用 descendants(它们都来自 ActiveSupport)调用 ObjectSpace.each_object

如果你读 it's doc,它说

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.

不是很清楚。但是 AFAIU 它遍历 GC 知道的所有对象。

所以实际情况是这样的:这个 class 是不可达的,除非你向 GC 询问它,然后它可以给你一个引用。 (如果你问我的话有点老套)

IMO 你不应该相信 subclasses 任何生产代码。似乎不可预测。也许,无论你想用 subclasses 实现什么,都可以用不同的方式完成吗? (但这是另一个 SO 问题的主题)