每个参数调用一次PHPUnit测试方法

时间:2020-01-27 22:53:03

标签: php phpunit

我有一个方法,在一次测试中将被多次调用,但每个参数仅被调用一次。因此,我想测试该方法只接收一次每个参数。例如,我在这里有一个mkdir函数,每个目录都将调用该函数来创建:

测试

$dirs = [
    "$parentDir/$siteName/assets/components",
    "$parentDir/$siteName/assets/layouts",
];

// iterate each directory 
foreach($dirs as $dir) {

    // and verify that mkdir was called with that argument only once
    $fileSystemMock->expects($this->once())
        ->method('mkdir')
        ->with($this->equalTo($dir));
}

正在测试的方法

public function createSite($siteName) {

    $fileSystem = $this->fileSystem;
    $parentDir = $this->parentDir;

    $componentsDir = "$parentDir/$siteName/assets/components";
    $layoutsDir = "$parentDir/$siteName/assets/layouts";
    $mediaDir = "$parentDir/$siteName/content/media";
    $sectionsDir = "$parentDir/$siteName/assets/sections";

    if (!$fileSystem->exists($componentsDir)) {
        $fileSystem->mkdir($componentsDir);
    }

    if (!$fileSystem->exists($layoutsDir)) {
        $fileSystem->mkdir($layoutsDir);
    }

但是,测试失败:

Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'/path/to/parent/best-widgets/assets/layouts'
+'/path/to/parent/best-widgets/assets/components'

希望这是有道理的。一次()是否不考虑with()参数?我不知道如何只检查一次带有每个参数的

1 个答案:

答案 0 :(得分:0)

您可以使用withConsecutive

$fileSystemMock->expects($this->exactly(count($dirs)))
  ->method('mkdir')
  ->withConsecutive(...array_map(function (string $dir) { 
     return [$this->equalTo($dir)]; 
  }, $dirs));

withConsecutive为每组参数期望值期望一个参数,因此array_map与解包运算符结合使用非常方便。

请注意,只有在以$dirs数组定义的相同顺序进行调用时,此方法才能通过。否则,似乎很难实施(顺便说一下,最近为此创建了GitHub issue)。

以上的Bonus PHP 7.4版本:

$fileSystemMock->expects($this->exactly(count($dirs)))
  ->method('mkdir')
  ->withConsecutive(...array_map(fn(string $dir) => [$this->equalTo($dir)], $dirs));
相关问题