如何阻止 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 问题的主题)
所以我正在尝试测试一个摘要 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 问题的主题)