PHPUnit测试中的模拟嵌套php默认功能
#教程 #php #测试 #phpunit

假设您有以下内容:

class ComposerFileService {
    public function fetchComposerJsonObject(string $composerJsonFilePath): ?object
    {
        return json_decode(file_get_contents($composerJsonFilePath));
    }
}

要在phpunit中测试此方法,请使用php-mock/php-mock-phpunit库。首先,安装它:

composer require --dev php-mock/php-mock-phpunit

第二步是在Phpunit测试类中使用\phpmock\phpunit\PHPMock特征。然后,我们可以编写一个单元测试:

/**
 * @dataProvider fetchComposerJsonObject_HappyFlow
 *
 * @param string $composerJsonFilePath
 * @param string $fileGetContentsMockValue
 * @param object $jsonDecodeMockValue
 */
public function testFetchComposerJsonObject_HappyFlow(
    string $composerJsonFilePath,
    string $fileGetContentsMockValue,
    object $jsonDecodeMockValue
) {
    $fileGetContentsMock = $this->getFunctionMock(dirname(ComposerFileService::class), 'file_get_contents');
    $fileGetContentsMock->expects($this->once())
        ->with($composerJsonFilePath)
        ->willReturn($fileGetContentsMockValue);

    $jsonDecodeMock = $this->getFunctionMock(dirname(ComposerFileService::class), 'json_decode');
    $jsonDecodeMock->expects($this->once())
        ->with($fileGetContentsMockValue)
        ->willReturn($jsonDecodeMockValue);

    $service = $this->getMockBuilder(ComposerFileService::class)
        ->disableOriginalConstructor()
        ->onlyMethods([])
        ->getMock();
    $result = $service->fetchComposerJsonObject($composerJsonFilePath);

    $this->assertEquals($jsonDecodeMockValue, $result);
}

此测试的数据提供商简直就是:

private function fetchComposerJsonObject_HappyFlow(): array {
    $faker = Factory::create();

    return [
        'happy flow' => [
            'composerJsonFilePath' => $faker->unique()->word(),
            'fileGetContentsMockValue' => $faker->unique()->word(),
            'jsonDecodeMockValue' => (object)[ 'key' => $faker->unique()->word()]
        ]
    ];
}

为了正确测试此方法,我们进行了以下操作:

  • 数据提供商中的$faker只是使用https://fakerphp.github.io来为我们的测试生成随机数据。与我们的示例无关。
  • 我们没有使用文件系统中的真实文件。单位测试不应这样做。
  • file_get_contentsjson_decode(php的默认值)函数未直接调用,而是被嘲笑。
  • 我们正在测试file_get_contents被调用一次,并具有$composerJsonFilePath的值。返回值是随机生成的(由Faker生成),并且在测试file_get_contents函数的背景下是无关的。我们只需要它即可正确测试json_decode
  • 我们正在测试json_decode被调用一次,带有file_get_contents返回的值。
  • 最后,我们正在测试我们的方法返回了调用json_decode的结果。

有关PHP默认功能嘲笑和间谍的更多信息和示例,请查看以下库: