PHPUnit:模拟不存在 类

PHPUnit: mock non-existing classes

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

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 方法进行单元测试,以检查创建的任务实例是否扩展了一些抽象 class。
是否有可能不在文件系统中创建示例 class 以检查继承约束?
谢谢大家!

是的,PHPUnit 可能 stub/mock class 不存在。简单做

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

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

PHPUnit 9 起,您应替换:

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

接受的答案是完美的,除了因为 PHPUnit 9 有一个问题,如果你需要模拟一个 class 需要是某个特定的实例。在那种情况下 \stdclass::class 不能使用。

并使用

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

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

以防其他人遇到同样的问题,幸运的是 setMethods 仍然有效,所以这在 PHPUnit 9 中仍然有效

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

请注意,setMethods 将在 PHPUnit 10

中删除

希望届时可以解决此问题。例如检查 allowMockingUnknownTypes 是否设置为 true。如果实施该检查,那么这也将起作用:

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