7

使用 PHPUnit 和模拟对象,我正在尝试测试一些get_class用于确定对象是否包含在过滤器中的代码。

这是要测试的类:

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

在测试中传递 Mock 的类名:

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