Qa\SoftMocks::redefineMethod PHP Method

redefineMethod() public static method

There are two already defined variables that you can use in fake code: $mm_func_args = func_get_args(); $params is array of references to supplied arguments (func_get_args() does not contain refs in PHP5) You can use SoftMocks::callOriginal(...) for accessing original function/method as well Example: class A { public function b($c, &$d) { var_dump($c, $d); } } SoftMocks::redefineMethod(A::class, 'b', '$e, &$f', '$f = "hello";'); $a = 2; (new A())->b(1, $a); // nothing is printed here, so we intercepted the call var_dump($a); // string(5) "hello"
public static redefineMethod ( string $class, string $method, string $functionArgs, string $fakeCode, boolean $strict = true )
$class string
$method string Method of class to be intercepted
$functionArgs string List of argument names
$fakeCode string Code that will be eval'ed instead of function code
$strict boolean If strict=false then method of declaring class will also be mocked
    public static function redefineMethod($class, $method, $functionArgs, $fakeCode, $strict = true)
    {
        if (self::$debug) {
            self::debug("Asked to redefine {$class}::{$method}({$functionArgs})");
        }
        if (SoftMocksTraverser::isClassIgnored($class)) {
            throw new \RuntimeException("Class {$class} cannot be mocked using Soft Mocks");
        }
        self::$mocks[$class][$method] = ['args' => $functionArgs, 'code' => $fakeCode];
        try {
            $Rm = new \ReflectionMethod($class, $method);
            self::$mocks[$class][$method]['code'] = self::generateCode($functionArgs, $Rm) . self::$mocks[$class][$method]['code'];
            if ($strict) {
                return;
            }
            $Dc = $Rm->getDeclaringClass();
            if ($Dc) {
                if ($Dc->getTraits() && ($DeclaringTrait = self::getDeclaringTrait($Dc->getName(), $method))) {
                    $Dc = $DeclaringTrait;
                }
                $decl_class = $Dc->getName();
                // do not mock declaring class again if there already exists a proper mock for it
                $no_mock_for_parent = empty(self::$mocks[$decl_class][$method]);
                $installed_from_current_mock = false;
                if (isset(self::$mocks[$class][$method]['installed_by']) && self::$mocks[$class][$method]['installed_by'] === $class) {
                    $installed_from_current_mock = true;
                }
                if ($no_mock_for_parent || $installed_from_current_mock) {
                    if (self::$debug) {
                        self::debug("Redefine also {$decl_class}::{$method}({$functionArgs})");
                    }
                    self::$mocks[$decl_class][$method] = self::$mocks[$class][$method] + ['installed_by' => $class];
                    self::$mocks[$class][$method]['decl_class'] = $decl_class;
                }
            }
        } catch (\Exception $e) {
            self::$mocks[$class][$method]['code'] = self::generateCode($functionArgs, null) . self::$mocks[$class][$method]['code'];
            if (self::$debug) {
                self::debug("Could not new ReflectionMethod({$class}, {$method}), cannot accept function calls by reference: " . $e);
            }
        }
    }

Usage Example

Example #1
0
 public static function applyMocks()
 {
     \QA\SoftMocks::redefineConstant('TEST_CONSTANT_WITH_VALUE_42', 43);
     \QA\SoftMocks::redefineConstant('\\Example::STATIC_DO_SMTH_RESULT', 'Example::STATIC_DO_SMTH_RESULT value changed');
     \QA\SoftMocks::redefineFunction('someFunc', '$a', 'return 55 + $a;');
     \QA\SoftMocks::redefineMethod(Example::class, 'doSmthStatic', '', 'return "Example::doSmthStatic() redefined";');
     \QA\SoftMocks::redefineMethod(Example::class, 'doSmthDynamic', '', 'return "Example->doSmthDynamic() redefined";');
 }
All Usage Examples Of Qa\SoftMocks::redefineMethod