kenjis / monkey-patch
对 exit()、函数、方法和常量进行 Monkey Patching
Requires
- php: ^7.3 || ^8.0
- ext-openssl: *
- ext-tokenizer: *
- nikic/php-parser: ^4.10
- phpunit/phpunit: ^9.5
Requires (Dev)
- bamarni/composer-bin-plugin: ^1.4
- kenjis/phpunit-helper: ^1.1
This package is auto-updated.
Last update: 2024-09-25 11:01:35 UTC
README
此包是 ci-phpunit-test 的 Monkey Patching 的独立包。
它提供了四个 Monkey Patcher。
ExitPatcher
:将exit()
转换为异常FunctionPatcher
:修补函数MethodPatcher
:修补用户定义类中的方法ConstantPatcher
:更改常量值
目录
需求
- PHP 7.3 或更高版本
安装
$ composer require --dev kenjis/monkey-patch
用法
注意:错误发生时的行号可能与实际源代码不同。请检查 Monkey Patching 创建的源代码缓存文件。
注意:使用此包会对测试速度产生负面影响。
配置
- 要启用 Monkey Patching,请将 bootstrap 内容 添加到您的 PHPUnit bootstrap 文件中。
- 要验证调用,请在您的 TestCase 类中使用 MonkeyPatchTrait。
将 exit()
转换为异常
此修补器将 exit()
或 die()
语句即时转换为异常。
如果您有一个如下所示的控制器
public function index() { $this->output ->set_status_header(200) ->set_content_type('application/json', 'utf-8') ->set_output(json_encode(['foo' => 'bar'])) ->_display(); exit(); }
测试用例可能如下所示
public function test_index() { try { $this->request('GET', 'welcome/index'); } catch (ExitException $e) { $output = ob_get_clean(); } $this->assertContains('{"foo":"bar"}', $output); }
修补函数
此修补器允许替换 PHPUnit 无法模拟的全局函数。
但它有一些限制。一些函数不能被替换,可能会引起错误。
因此,默认情况下,我们只能替换 FunctionPatcher 中的十几个预定义函数。
public function test_index() { MonkeyPatch::patchFunction('mt_rand', 100, 'Welcome::index'); $output = $this->request('GET', 'welcome/index'); $this->assertContains('100', $output); }
MonkeyPatch::patchFunction()
替换 Welcome::index
方法中的 PHP 原生函数 mt_rand()
,在测试方法中返回 100
。
注意:如果您不带第三个参数调用 MonkeyPatch::patchFunction()
,则测试方法中所有调用的函数(位于 include_paths
中,不在 exclude_paths
中)都将被替换。例如,库代码中的一个函数可能会被替换,导致意外结果。
更改返回值
您可以使用 PHP 闭包更改修补函数的返回值
MonkeyPatch::patchFunction( 'function_exists', function ($function) { if ($function === 'random_bytes') { return true; } elseif ($function === 'openssl_random_pseudo_bytes') { return false; } elseif ($function === 'mcrypt_create_iv') { return false; } else { return __GO_TO_ORIG__; } }, Welcome::class );
修补其他函数
如果您想修补其他函数,可以在 MonkeyPatchManager::init()
中的 functions_to_patch 中添加它们。
但存在一些已知的限制
- 参数通过引用调用的修补函数不起作用。
- 如果您将非公共回调传递给修补函数,可能会看到可见性错误。例如,您将
[$this, 'method']
传递给array_map()
,并且类中的method()
方法不是公共的。
修补用户定义类中的方法
此修补器允许替换用户定义类中的方法。
public function test_index() { MonkeyPatch::patchMethod( Category_model::class, ['get_category_list' => [(object) ['name' => 'Nothing']]] ); $output = $this->request('GET', 'welcome/index'); $this->assertContains('Nothing', $output); }
MonkeyPatch::patchMethod()
用来替换 Category_model
中的 get_category_list()
方法,在测试方法中会返回 [(object) ['name' => 'Nothing']]
。
修补常量
这个修补器允许替换常量值。
public function test_index() { MonkeyPatch::patchConstant( 'ENVIRONMENT', 'development', Welcome::class . '::index' ); $output = $this->request('GET', 'welcome/index'); $this->assertContains('development', $output); }
MonkeyPatch::patchConstant()
用于替换 Welcome::index
方法中常量 ENVIRONMENT
的返回值。
存在一些已知的限制:
- 不能修补作为函数参数默认值使用的常量。
- 不能修补作为常量声明默认值使用的常量。
- 不能修补作为属性声明默认值使用的常量。
- 不能修补作为静态变量声明默认值使用的常量。
类参考
请参阅 ci-phpunit-test 文档。
许可
本软件包采用 MIT 许可证授权。
请查看 LICENSE
。