mcannucci/aspect-override

通过方面重载函数

0.5.0 2022-10-22 02:32 UTC

This package is auto-updated.

Last update: 2024-09-24 05:10:50 UTC


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的极大启发