假设您有以下内容:
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_contents
和json_decode
(php的默认值)函数未直接调用,而是被嘲笑。 - 我们正在测试
file_get_contents
被调用一次,并具有$composerJsonFilePath
的值。返回值是随机生成的(由Faker生成),并且在测试file_get_contents
函数的背景下是无关的。我们只需要它即可正确测试json_decode
。 - 我们正在测试
json_decode
被调用一次,带有file_get_contents
返回的值。 - 最后,我们正在测试我们的方法返回了调用
json_decode
的结果。
有关PHP默认功能嘲笑和间谍的更多信息和示例,请查看以下库:
- https://github.com/php-mock/php-mock-一个嘲笑非确定性内置PHP功能的测试库;
- https://github.com/php-mock/php-mock-phpunit-将功能模拟库php mock与phpunit集成;