7

get_classPHPUnit とモック オブジェクトを使用して、オブジェクトがフィルターに含まれているかどうかを判断するために使用するコードをテストしようとしています。

テストするクラスは次のとおりです。

class BlockFilter implements FilterInterface
{
    private $classes;

    public function __construct(array $classes = array())
    {
        $this->classes = $classes;
    }

    public function isIncluded(NodeTraversableInterface $node)
    {
        if (Type::BLOCK != $node->getDocumentType()) {
            return false;
        }

        if (! empty($this->classes)) {
            /*** HERE IS THE PROBLEM: ***/
            return in_array(get_class($node), $this->classes);
        }

        return true;
    }
}

これが私の単体テストの方法です:

public function testIfContainerBlockIsIncluded()
{
    $containerBlock = $this->getMock('Pwn\ContentBundle\Document\ContainerBlock');
    $containerBlock->expects($this->any())->method('getDocumentType')->will($this->returnValue(Type::BLOCK));

    $filter = new BlockFilter(array('Pwn\ContentBundle\Document\ContainerBlock'));
    $this->assertTrue($filter->isIncluded($containerBlock));
}

モック オブジェクト$containerBlockは実際のオブジェクトのように動作しますPwn\ContentBundle\Document\ContainerBlock。を使用したコードでさえ機能しinstanceofます (PHPUnit はそれを実際のクラスのサブクラスにするためです)。

テストされるコードget_classは、クラスの文字列値を取得し、それを期待されるクラス名の配列と比較するために使用します。残念ながら、モック オブジェクトの場合、get_class は次のようなものを返します。

Mock_ContainerBlock_ac231064

(_ac231064 サフィックスは呼び出しごとに変わります)。

これによりテストが失敗するので、どのようなオプションがありますか?

  • get_class を使用しないようにコードを修正しますか? これは、テスト可能なコードを作成しようとするときに get_class を使用しないことを意味します。
  • モックの代わりに ContainerBlock クラスの実際のインスタンスを使用しますか? これは、両方のクラスを一度に効果的にテストしていることを意味します。
  • 皆さんが提案しようとしている他の驚くほど巧妙なトリック??? ;)

助けてくれてありがとう...

4

1 に答える 1

3

テストでモックのクラス名を渡します。

new BlockFilter(array(get_class($this->containerBlock)));
于 2013-01-04T12:11:47.097 に答える