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 に答える