如何重新加载一个 Ruby 类

9
在我们的许多课程中,为了提高性能,我们会对耗时操作进行缓存。例如:

def self.foo
    @foo ||= get_foo
end 

这在应用程序中表现很好,但是测试(RSpec)因为这些记忆化变量而失败了。当我们期望新鲜值时,来自第一个测试的值会在后续测试中返回。

所以问题是:我该如何重新加载类?或者删除所有记忆化变量?

2个回答

9
将一个after(或before)块添加到示例组中,以移除实例变量(假设所涉及的对象是主题):
after do
  subject.instance_variable_set(:@foo, nil)
end

或者修复问题。拥有一个记忆化的类实例变量有点不妙,因为它永远不会改变。正常的实例变量不会有这个问题,因为你会为每个测试创建一个新的对象。


谢谢,我猜那个方法也可以,但和另一个解决方案一样,这会使测试维护变得困难,因为你需要显式地取消设置变量。 - Sebastian
是的,我倾向于一开始就不进行记忆化。 - Sebastian
没错。作为一般准则:如果编写测试很困难,那么被测试的代码真的是有问题的。 - Andrew Marshall
当你记忆化配置值时怎么办?这仍然是一种不好的做法吗?例如:@key ||= File.read(key_file_path) - Sebastian

5

构建你的类和测试,使得缓存数据在有效时保持正确或被删除。考虑添加一个清除缓存的方法,并在rspec的before块中调用它。


是的,我认为这是最好的方法和更清晰的解决方案。谢谢。 - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接