测试将get_class与PHPUnit模拟对象一起使用的代码

时间:2013-01-04 12:04:27

标签: php phpunit

使用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来获取类的字符串值,并将其与预期类名称数组进行比较。不幸的是,对于mock对象,get_class返回如下内容:

Mock_ContainerBlock_ac231064

(_ac231064后缀在每次调用时都会更改。)

这导致我的测试失败,那么我的选择是什么?

  • 重做代码以避免使用get_class?这意味着在尝试编写可测试代码时不应使用get_class。
  • 使用ContainerBlock类的实际实例而不是模拟?这意味着我们可以同时有效地测试这两个类。
  • 你要提出的其他一些非常聪明的伎俩??? ;)

感谢您的帮助......

1 个答案:

答案 0 :(得分:3)

在测试中传递Mock的类名:

new BlockFilter(array(get_class($this->containerBlock)));