Ruby 规范不作为创建动态类的“沙盒”运行
我有一个带有define方法的模块,它动态创建一个类,如下所示:Ruby 规范不作为创建动态类的“沙盒”运行,ruby,rspec,metaprogramming,ruby-2.0,Ruby,Rspec,Metaprogramming,Ruby 2.0,我有一个带有define方法的模块,它动态创建一个类,如下所示: require "active_support/all" class SomeBaseClass # code end module MyModule def self.define(_class_name) class_name = _class_name.classify Object.const_set(class_name, Class.new(SomeBaseClass)) end end
require "active_support/all"
class SomeBaseClass
# code
end
module MyModule
def self.define(_class_name)
class_name = _class_name.classify
Object.const_set(class_name, Class.new(SomeBaseClass))
end
end
然后,如果我这样做:MyModule.define:myu类,我将得到:MyClass
我的规格:
describe "#define" do
it "creates a dynamic class" do
MyModule.define("my_class")
expect(subject.const_defined?("MyClass")).to be_truthy
end
end
这个很好用。。。但是当我创建一个定义MyClass的新规范时,我得到以下警告:警告:已初始化常量MyClass
发生这种情况是因为我在以前的规范中创建了MyClass。所以,问题是:如何避免这种情况?我希望每个规格都有一个新的开始
更新:基于@giglemad答案的解决方案
您可以根据名称+某种约定每次定义不同的类名。我使用时间戳这样做
def nano_timestamp_string
Time.now.to_f.to_s.sub('.','')
end
当您需要一些独特的东西,但仍然希望以相同的方式编写测试时,您几乎可以重用该约定。例如,我用它来发送独特的电子邮件。如果您仍然要定义一个同名的常量,然后再定义它,那么您可能需要使用
Object.send(:remove_const,:Myconst)
rspec有stub_const,它允许您定义类之类的常量,并在测试后自动清理它们。我认为选项2更干净。
Object.send(:remove_const,:Myconst)