【问题标题】:PHPUnit: mock non-existing classesPHPUnit:模拟不存在的类
【发布时间】:2015-03-23 09:49:32
【问题描述】:

是否可以在 PHPUnit 中创建一个不存在的类的模拟?
假设我有一些类创建另一个类的实例,例如:

class TaskRunner
{
    public function runTasks()
    {
        // Run through some loop to get tasks and store each in $taskName
        // Get task instance by given task name 
        $task = $this->getTaskInstance($taskName);
        if ($task instanceof AbstractTask) {
            $task->run();
        }
    }

    protected function getTaskInstance($taskName)
    {
        // Just an example
        return new $taskName();
    }
}

我想对runTasks 方法运行单元测试,以检查创建的任务实例是否扩展了某些抽象类。
是否有可能不在文件系统中创建示例类来检查继承约束?
谢谢大家!

【问题讨论】:

  • ->getMock('AbstractTask')?
  • @PeeHaa 好的,可以让条件运行为真。非AbstracTask-扩展类呢?模拟stdClass?
  • 您也可以使用 phpunit 模拟具体的类。但您更有可能想输入一个界面。
  • @PeeHaa 当然,我明白你的意思。但是让我们假设有两个类,一个扩展了AbstractClass,第二个没有扩展,纯基类。我不想在文件系统中创建它们,但我确实想模拟它们。第一个,好的,我可以模拟AbstractClass,它可以完成这项工作。第二个呢?它不实现任何接口,也不扩展任何其他类。我想为instanceof 条件失败写一个测试。

标签: unit-testing mocking phpunit


【解决方案1】:

是的,可以存根/模拟 PHPUnit 中不存在的类。干脆做

 $this->getMockBuilder('NameOfClass')->setMethods(array('foo'))->getMock();

创建一个不存在的类 NameOfClass 的对象,该对象提供一种方法 foo(),可以像往常一样使用 API 进行配置。

由于PHPUnit 9,你应该替换:

  • 'NameOfClass'\stdClass::class
  • setMethodsaddMethods
$this->getMockBuilder(\stdclass::class)->addMethods(array('foo'))->getMock();

【讨论】:

  • 不,PHPUnit 不会抛出异常。您为什么不直接尝试而不是询问?
  • 我是通过电话接听的,当时我无法自己测试 :) 抱歉。
  • @SebastianBergmann,由于在 v9 中弃用了 setMethods(),此代码不适用于 PHPUnit 10。是否可以为现代 PHPUnit 模拟 API 中不存在的类创建模拟?
  • @rodion.arr 现在您可以使用方法addMethods。见github.com/sebastianbergmann/phpunit/pull/3687
  • @rodion.arr 我编辑了答案以添加新方法 addMethods 并将虚拟名称替换为最小的现有类:stdClass。
【解决方案2】:

接受的答案是完美的,除了由于 PHPUnit 9 存在一个问题,如果您需要模拟一个需要属于某个实例的类。在这种情况下,\stdclass::class 不能使用。

并使用

$this->getMockBuilder('UnexistentClass')->addMethods(['foo'])->getMock();

将导致Class UnexistentClass does not exist,因为addMethod 会根据给定的类方法检查给定的方法。

如果其他人遇到同样的问题,幸运的是 setMethods 仍然有效,所以这仍然适用于 PHPUnit 9

$this->getMockBuilder('UnexistentClass')->setMethods(['foo'])->getMock();

请注意,setMethods 将在 PHPUnit 10

中被删除

希望届时会有解决此问题的方法。例如检查allowMockingUnknownTypes 是否设置为true。如果实施了该检查,这也将起作用:

$this->getMockBuilder('UnexistentClass')->allowMockingUnknownTypes()
->addMethods(['foo'])->getMock();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2018-02-08
    • 2021-10-31
    • 2017-04-16
    相关资源
    最近更新 更多