PHPUnit:模拟不存在的类

Kub*_*a T 15 phpunit unit-testing mocking

是否可以在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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Seb*_*ann 33

是的,可以存根/模拟PHPUnit不存在的类.只需$this->getMockBuilder('NameOfClass')->setMethods(array('foo'))->getMock();创建一个NameOfClass提供一种方法的非existant类的对象foo(),可以像往常一样使用API​​进行配置.

  • @rodion.arr 现在您可以使用“addMethods”方法。请参阅 https://github.com/sebastianbergmann/phpunit/pull/3687 (4认同)
  • 不,PHPUnit不会抛出异常.你为什么不继续尝试而不是问? (3认同)
  • @SebastianBergmann,由于 v9 中“setMethods()”的弃用,此代码不适用于 PHPUnit 10。是否可以为现代 PHPUnit 模拟 API 中不存在的类创建模拟? (2认同)

小智 5

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

并使用

$this->getMockBuilder('UnexistentClass')->addMethods(['foo'])->getMock();
Run Code Online (Sandbox Code Playgroud)

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

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

$this->getMockBuilder('UnexistentClass')->setMethods(['foo'])->getMock();
Run Code Online (Sandbox Code Playgroud)

请注意,这setMethods将在PHPUnit 10中删除

希望到时候这个问题能够得到解决。例如检查是否allowMockingUnknownTypes设置为true。如果实施该检查,那么这也将起作用:

$this->getMockBuilder('UnexistentClass')->allowMockingUnknownTypes()
->addMethods(['foo'])->getMock();
Run Code Online (Sandbox Code Playgroud)