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

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

Mock_ContainerBlock_ac231064

(_ac231064 后缀在每次调用时发生变化)。

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

  • 重写代码以避免使用 get_class?这意味着在尝试编写可测试代码时不应使用 get_class。
  • 使用 ContainerBlock 类的真实实例而不是模拟?这意味着我们同时有效地测试了这两个类。
  • 你们都会建议其他一些非常聪明的技巧??? ;)

感谢您的帮助...

最佳答案

在测试中传递 Mock 的类名:

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

关于php - 将 get_class 与 PHPUnit 模拟对象一起使用的测试代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14156868/

相关文章:

php - 如何更改定期付款交易的信用卡号码?

phpunit 与 dbunit : how can i keep data in my db across tests?

symfony - 如何在 Symfony 4 中为测试环境设置数据库

PHP 正在向 MySQL 插入问号

php - 如何在 PHPUnit 中运行特定文件?

php - 禁用 PHPUnit 代码覆盖率输出中的颜色

PHPUnit - 同一类的多个 stub

javascript - 隐藏按钮并使用 ajax 启用另一个按钮

php - 在 Laravel 中放置自定义/新类文件的位置?

php - 用 imagemagick 创建图片太慢了。怎么提高?