2

我有这种情况,在其中我定义了一个实例方法,它返回类本身的“安全篡改”测试虚拟对象。

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

现在你可以开始笑了。

我的主要问题是,在“duplicated = sub.dup”行中,我复制了子类测试类,那行有什么意义吗?对我来说,这是伏都教,我这样做只是为了尽量减少对假人进行的篡改对测试类本身的任何负面影响。我通过#dup-ping 课程获得了什么吗?

附带问题:如果我在做一些公然可笑的事情,请告诉我。我简化了这段代码,但我不确定它是如何工作的(更复杂的原始代码确实可以按我的预期工作),但我希望你至少能明白这一点。另外,请那里的向导向我推荐一个好的模拟框架。

4

1 回答 1

3

如果您想在不践踏原始类的情况下更改常量或其他类范围的数据之类的事情,那么复制它似乎是要走的路 -

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
于 2012-05-07T05:08:22.033 回答