avris / function-mock
用于模拟全局函数的轻量级类
v1.0.1
2018-01-09 20:28 UTC
Requires
- php: ^7.0
Requires (Dev)
- phpunit/phpunit: ^6.5
- squizlabs/php_codesniffer: ^3.2
- symfony/var-dumper: ^v4.0
This package is auto-updated.
Last update: 2024-09-12 04:10:48 UTC
README
FunctionMock 是一个简单优雅的方式来在测试中模拟系统/全局函数。
安装
composer require --dev avris/function-mock
用法
假设你有一个将内容写入文件的类
<?php
namespace App\Service;
class WorkService
{
public function work(int $input): bool
{
$result = 'correctResult'; // ... calculate the result somehow
$filename = '/tmp/foo';
return file_put_contents($filename, $result);
}
}
为了测试它,而不实际使用文件系统,你可以使用 FunctionMock
<?php
namespace App\Test;
use App\Service\WorkService
use PHPUnit\Framework\TestCase;
class ServiceTest extends TestCase
{
/** @var WorkService */
private $service;
protected function setUp()
{
$this->service = new WorkService();
}
protected function tearDown()
{
FunctionMock::clean();
}
public function testWork()
{
$mock = FunctionMock::create('App', 'file_put_contents', true);
$returnValue = $this->service->work(8);
$this->assertTrue($returnValue);
$this->assertEquals([['/tmp/foo', 'correctResult']], $mock->getInvocations());
}
}
如果你的测试与被测试类在同一命名空间中,建议使用 __NAMESPACE__
。
第三个参数,模拟函数的返回值,可以是字面量或可调用对象
$mock = FunctionMock::create(__NAMESPACE__, 'file_put_contents', function ($filename, $data) {
return $filename === '/tmp/foo';
});
你可以通过调用 $mock->disable()
和 $mock->enable()
来禁用/启用模拟,以及通过 $mock->clearInvocations()
清除记录的调用列表。
已知限制
FunctionMock 是通过 file_get_contents
在 App\Service
命名空间内引用函数 App\Service\file_get_contents
并仅在它未定义时回退到全局 \file_get_contents
来工作的。
FunctionMock 会动态定义这个 App\Service\file_get_contents
函数,并使其在运行时可根据你的需求进行调整。
- 如果你在注册模拟之前已经在
App\Service
内调用了file_get_contents
,PHP 将继续使用全局函数,并且不能再被覆盖。 - 如果你在测试类中使用了
\file_get_contents
(显式全局命名空间),显然无法对其进行模拟。 - 注册后,模拟函数实际上不能被真正删除,只能被禁用。
版权
- 作者: Andre Prusinowski (Avris.it)
- 许可证: MIT