Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Autoload Override Laravel Package

adriansuter/php-autoload-override

Override PHP autoloading to take control of how classes are resolved. php-autoload-override lets you hook into Composer’s autoloader to swap, alias, or redirect class loading—useful for debugging, testing, and patching vendor code without forks.

View on GitHub
Deep Wiki
Context7

PHP-Autoload-Override

Build Status Coverage Status Total Downloads License

This library allows overriding fully qualified function calls inside your class methods in order to be able to mock them during testing.

NOTE: The library can be used for other scenarios as well. But we recommend using it for testing purposes only.

PHP-Autoload-Override Website

Requirements

  • PHP 8.2 or later
  • Composer with PSR-4 (PSR-0 is not supported)

Installation

$ composer require --dev adriansuter/php-autoload-override 2.0

Usage with PHPUnit

Say we want to unit test the following class Probability.

namespace My\App;

class Probability
{
    public function pick(int $probability, string $color1, string $color2): string
    {
        if (\rand(1, 100) <= $probability) {
            return $color1;
        } else {
            return $color2;
        }
    }
}

The class has one method pick that takes a probability (between 0 and 100) and two color names as arguments. The method would then use the rand function of the global scope to generate a random number and if the generated number is smaller equal to the given probability, then the method would return the first color, otherwise the method would return the second color.

The problem

As we cannot control the output of the rand function (it is in global scope), we cannot unit test that method. Well, until now. Using the PHP-Autoload-Override library, it is possible to override the rand function and therefore control its generated random number.

The solution

After installing the PHP-Autoload-Override library, we would open the bootstrap script of our test suite (see also PHPUnit Configuration). There we will write the following code

// tests/bootstrap.php

/** @var \Composer\Autoload\ClassLoader $classLoader */
$classLoader = require_once __DIR__ . '/../vendor/autoload.php';

\AdrianSuter\Autoload\Override\Override::apply($classLoader, [
    \My\App\Probability::class => [
        'rand' => function ($min, $max): int {
            if (isset($GLOBALS['rand_return'])) {
                return $GLOBALS['rand_return'];
            }

            return \rand($min, $max);
        }
    ]
]);

Now the class Probability would be loaded into the PHPUnit runtime such that all function calls to the global scoped rand() function in the class Probability get overridden by the closure given above.

Our test class can now be written as follows.

namespace My\App\Tests;

use My\App\Probability;
use PHPUnit\Framework\TestCase;

final class ProbabilityTest extends TestCase
{
    protected function tearDown()
    {
        if (isset($GLOBALS['rand_return'])) {
            unset($GLOBALS['rand_return']);
        }
    }

    public function testPick()
    {
        $p = new Probability();

        $GLOBALS['rand_return'] = 35;

        $this->assertEquals('blue', $p->pick(34, 'red', 'blue'));
        $this->assertEquals('red', $p->pick(35, 'red', 'blue'));
    }
}

The test case testPick would call the pick method two times. As we have overridden the \rand function, we can control its returned value to be always 35. So the first call checks, if the else-block gets executed. The second one checks, if the if-block gets executed. Hooray, 100% code coverage.

Note that this override would only be applied during the unit tests.

Learn More

License

The PHP-Autoload-Override library is licensed under the MIT license. See License File for more information.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport