mcannucci / aspect-override
通过方面重载函数
0.5.0
2022-10-22 02:32 UTC
Requires
- php: ^7.1 | ^8
Requires (Dev)
- pestphp/pest: ^1.21
- phpstan/phpstan: ^1.5.0
- rawr/cross-data-providers: ^2.3
README
此库在版本1.0.0之前是实验性的,更新时可能会出错
重载测试中的方法和函数(通过面向方面的方法)
注意:此库仅适用于测试环境,在生产环境中没有稳定性保证
关于
此库旨在成为测试任何PHP项目的“瑞士军刀”,允许您以任何您想要的方式修改程序的执行。
功能
- 覆盖任何类型的类方法,静态或非静态
- 覆盖任何函数的功能,无论它是否有命名空间或全局
- 在调用函数之前覆盖函数的参数
- 在调用函数之后覆盖函数的返回值
- 即使函数参数是通过引用传递的,也可以修改函数参数
- 框架和自动加载器无关,与任何PHP代码库兼容(例如:Composer,常规require path/to/my/code.php)
入门指南
安装
composer require --dev mcannucci/aspect-override
引导
要启用重载函数和类方法,AspectOverride需要初始化一些流处理器,以执行使类方法和函数重写功能生效的代码转换
<?php require __DIR__ . '/../vendor/autoload.php'; AspectOverride\Facades\AspectOverride::initialize( AspectOverride\Core\Configuration::create() ->setDirectories([ __DIR__ . '/../app' ]) ->setExcludedDirectories([ __DIR__ . '/../app/excluded' ]) );
用法
重载类方法
use AspectOverride\Override; class MyClass { public function myMethod() { return false; } public static function myStaticMethod() { return false; } } // for any instance of 'MyClass', return true for the method 'myMethod' and 'myStaticMethod' instead of false Override::method(MyClass::class, 'myMethod', function(){ return true; }); Override::method(MyClass::class, 'myStaticMethod', function(){ return true; }); // Will work if it's a static or instantiated method MyClass::myStaticMethod() // true; (new MyClass)->myMethod(); // true;
在运行前重载类方法的参数
use AspectOverride\Override; class MyClass { public static function echoThis(int $a) { echo $a; } } // Before the function 'echoThis' runs we change $a to be incremented Override::method(MyClass::class, 'echoThis', function(int $a){ return [$a + 1] }); MyClass::echoThis(2) // 3;
在运行前重载特定类方法的参数
use AspectOverride\Override; class MyClass { public static function echoSecondArg(int $a, int $b) { echo $b; } } // Before the function 'echoSecondArg' runs we only modify the second argument and keep the first one as is Override::before(MyClass::class, 'echoSecondArg', function(int $a, int $b){ return ['b' => $b + 1] }); MyClass::echoSecondArg(2,3) // 4;
重载方法的返回值
use AspectOverride\Override; class MyClass { public static function echoOne() { echo 1; } } // After the function 'echoOne' runs, we increment the result by one Override::after(MyClass::class, 'echoOne', function($a){ return $a + 1; }); MyClass::echoOne() // 2;
重载函数的返回值
use AspectOverride\Override; Override::function('time', function(){ return 1000; }); time() // 1000;
您可能会有的问题
Q:这是怎么工作的,我以为你无法在PHP中重新定义方法和函数?
A:当文件在PHP中加载时,它通过PHP的流,由于PHP支持流周围的包装器,我们可以在PHP执行它之前重写代码以包含覆盖功能
Q:这个库真的很奇怪,我讨厌它,为什么不正常测试代码呢?
A:我希望我工作的所有代码库都可以测试 😈
Q:为什么行号不匹配或逐步调试时需要多次单击向上跳过?
A:由于我们正在重写源代码以重写方法和函数。插入语句以提前返回另一个值,替换参数或调用并返回“重写”函数的结果。这似乎比逐步调试被覆盖的代码(如果可能的话)要好
版本管理
SemVer用于版本管理。有关可用的版本,请参阅此存储库的标签。
许可
本项目采用MIT许可 - 有关详细信息,请参阅LICENSE.md文件
致谢
功能在很大程度上受到AspectMock的启发,并在通过PHP流进行猴子补丁方面受到php-vcr的极大启发