我遇到了这种情况,其中我定义了一个实例方法,该方法返回类本身的“安全篡改”测试虚拟对象。
require 'test/unit'
require 'shoulda'
module TestExtension
def provides_tested_class_dummy
self.class_exec do
def tested_class_dummy
txt = "class #{@tested_class.name}Dummy < #{@tested_class.name}; end"
sub = self.singleton_class.class_eval txt
duplicated = sub.dup
duplicated.class_exec do
# do evil things to the dummy,
# such as redefining constants and stubbing methods
end
end
end
end
end
Test::Unit::TestCase.extend TestExtensions
请先别笑。我这样做是因为它适合我需要做的事情,即测试类并对他们的假人做坏事,而不以任何方式接触测试的类。
class SomeClass
# define some constants
# define some methods
end
然后,测试它:
class SomeClassTest < Test::Unit::TestCase
@tested_class = ::SomeClass
provides_tested_class_dummy()
should "somehow comply" do
dummy = tested_class_dummy()
assert_kind_of Module, dummy
# other assertions about the dummy's behavior
end
end
现在你可以开始笑了。
我的主要问题是,在“duplicate = sub.dup”行中,我复制了子类化的测试类,该行有任何意义吗?对我来说,这是巫术,我这样做只是为了尽量减少对虚拟对象的篡改对测试类本身的负面影响。通过 #dup-ping 一个类(class)我能得到什么吗?
附带问题:如果我正在做一些明显可笑的事情,请告诉我。我简化了这段代码,我不太确定它是如何工作的(更复杂的原始代码确实按照我的预期工作),但我希望你至少能明白这个想法。另外,请那里的向导给我推荐一个好的模拟框架。
最佳答案
如果你想做一些事情,比如改变常量或其他类范围的数据而不破坏原始类,复制它看起来是一个不错的选择 -
class Lion
ROAR = 'roar!'
end
L2 = Lion.dup
puts Lion::ROAR # "roar!"
puts Lion::ROAR.object_id # 2152285120
puts L2::ROAR # "roar!"
puts L2::ROAR.object_id # 2152285120
L2::ROAR = 'rawrrr'
puts Lion::ROAR # "roar!"
puts Lion::ROAR.object_id # 2152285120
puts L2::ROAR # "rawrrr"
puts L2::ROAR.object_id # 2152285000
关于ruby - 复制 Ruby 类有什么用吗? (我正在做粗俗的 mock 。),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10476348/