PHPackages                             adriansuter/php-autoload-override - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. adriansuter/php-autoload-override

ActiveLibrary[Testing &amp; Quality](/categories/testing)

adriansuter/php-autoload-override
=================================

Override global scoped fully qualified function calls inside your class methods in order to be able to mock them during testing.

2.1(2mo ago)2366.4k↑27.7%3[3 PRs](https://github.com/adriansuter/php-autoload-override/pulls)16MITPHPPHP ^8.2CI failing

Since Nov 23Pushed 1w ago2 watchersCompare

[ Source](https://github.com/adriansuter/php-autoload-override)[ Packagist](https://packagist.org/packages/adriansuter/php-autoload-override)[ Docs](https://adriansuter.github.io/php-autoload-override/)[ RSS](/packages/adriansuter-php-autoload-override/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (8)Dependencies (10)Versions (15)Used By (16)

PHP-Autoload-Override
=====================

[](#php-autoload-override)

[![Build Status](https://github.com/adriansuter/php-autoload-override/workflows/Tests/badge.svg?branch=master)](https://github.com/adriansuter/php-autoload-override/actions?query=branch:master)[![Coverage Status](https://camo.githubusercontent.com/74aaca7d6a478aa07c9b5614195fa289843216f1f4ab907344f3c329b4646bfa/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f61647269616e73757465722f7068702d6175746f6c6f61642d6f766572726964652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/adriansuter/php-autoload-override?branch=master)[![Total Downloads](https://camo.githubusercontent.com/65657d247d99e661efdb9ac4ff5808bd43aaa441bc951535d13260b7e0035eb3/68747470733a2f2f706f7365722e707567782e6f72672f61647269616e73757465722f7068702d6175746f6c6f61642d6f766572726964652f646f776e6c6f616473)](https://packagist.org/packages/adriansuter/php-autoload-override)[![License](https://camo.githubusercontent.com/0f8a59612847266aa273d21509a57f4698c23eca84fb934830f536fcc7c9d28d/68747470733a2f2f706f7365722e707567782e6f72672f61647269616e73757465722f7068702d6175746f6c6f61642d6f766572726964652f6c6963656e7365)](https://packagist.org/packages/adriansuter/php-autoload-override)

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](https://adriansuter.github.io/php-autoload-override/)

Requirements
------------

[](#requirements)

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

Installation
------------

[](#installation)

```
composer require --dev adriansuter/php-autoload-override ^2.0
```

Usage with [PHPUnit](https://phpunit.de/)
-----------------------------------------

[](#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) forClass(Probability::class, ['rand' => \rand(...)])
    ->apply($classLoader);
```

Each entry in `forClass()` maps a function name to its real implementation, written as a [first-class callable](https://www.php.net/manual/en/functions.first_class_callable_syntax.php). `OverrideFactory` generates the override closure automatically: when a test sets a mock value via `MockRegistry::set()`, that value is returned; otherwise the real `\rand()` is called. No mock value is registered initially, so non-test code is unaffected.

For multiple classes, chain `forClass()` calls:

```
OverrideFactory::create()
    ->forClass(Clock::class,       ['time' => \time(...)])
    ->forClass(Probability::class, ['rand' => \rand(...)])
    ->apply($classLoader);
```

If you need the raw declarations array instead (e.g. for an `AbstractIntegrationTestCase`), use `build()` instead of `apply()`:

```
protected function getOverrideDeclarations(): array
{
    return OverrideFactory::create()
        ->forClass(Probability::class, ['rand' => \rand(...)])
        ->build();
}
```

### Writing the test

[](#writing-the-test)

Set a mock value with `MockRegistry::set()` before calling the code under test, and reset it in `tearDown()` so it does not affect other tests:

```
namespace My\App\Tests;

use AdrianSuter\Autoload\Override\MockRegistry;
use My\App\Probability;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;

final class ProbabilityTest extends TestCase
{
    protected function tearDown(): void
    {
        MockRegistry::reset(Probability::class);
    }

    #[Test]
    public function pickReturnsSecondColorWhenRandExceedsProbability(): void
    {
        MockRegistry::set(Probability::class, 'rand', 35);

        $p = new Probability();
        $this->assertSame('blue', $p->pick(34, 'red', 'blue'));
    }

    #[Test]
    public function pickReturnsFirstColorWhenRandMeetsProbability(): void
    {
        MockRegistry::set(Probability::class, 'rand', 35);

        $p = new Probability();
        $this->assertSame('red', $p->pick(35, 'red', 'blue'));
    }
}
```

`MockRegistry::reset(Probability::class)` clears only the overrides for that class. Call `MockRegistry::reset()` without arguments to clear all registered overrides at once.

Note that these overrides are only applied during the unit tests.

### Sharing an override across multiple classes

[](#sharing-an-override-across-multiple-classes)

`MockRegistry::set()` registers an override for one specific class. To register a fallback that applies to every class, use `setGlobal()`:

```
MockRegistry::setGlobal('time', 1574333284);
```

If a class also has a per-class override for the same function, the per-class value takes priority. Reset only the global overrides with `MockRegistry::resetGlobal()`.

### Using `Override::apply()` directly

[](#using-overrideapply-directly)

If you register overrides via `Override::apply()` directly rather than using `OverrideFactory`, you write the closure yourself. `MockRegistry::get()` takes three arguments: the class name, the function name, and a default that is returned when no mock is registered:

```
Override::apply($classLoader, [
    Probability::class => [
        'rand' => function (int $min, int $max): int {
            return MockRegistry::get(Probability::class, 'rand', \rand($min, $max));
        }
    ]
]);
```

Be aware that the third argument — `\rand($min, $max)` — is evaluated on every call, even when a mock value is set. This is harmless for `\rand()`, but if the real function is expensive or has side effects that must be avoided when a mock is active, guard the call with `MockRegistry::has()`:

```
'rand' => function (int $min, int $max): int {
    if (MockRegistry::has(Probability::class, 'rand')) {
        return MockRegistry::get(Probability::class, 'rand');
    }
    return \rand($min, $max);
}
```

> **Note:** Using `$GLOBALS` inside override closures still works and remains fully supported. `MockRegistry` is a cleaner alternative, not a replacement — existing code does not need to be migrated.

Learn More
----------

[](#learn-more)

- [PHP-Autoload-Override Website](https://adriansuter.github.io/php-autoload-override/)

License
-------

[](#license)

The PHP-Autoload-Override library is licensed under the MIT license. See [License File](LICENSE) for more information.

###  Health Score

62

—

FairBetter than 99% of packages

Maintenance92

Actively maintained with recent releases

Popularity40

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 86.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~260 days

Recently: every ~378 days

Total

10

Last Release

72d ago

Major Versions

v0.1-beta → 1.02020-01-04

1.5 → 2.02025-01-24

PHP version history (4 changes)v0.1-alphaPHP ^7.1

1.2PHP ^7.2 || ^8.0

1.3PHP ^7.3 || ^8.0

2.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/4ff41e3338b4e847e43441cf54099844bae3c789b409a378f8f6374d37ba1057?d=identicon)[adriansuter](/maintainers/adriansuter)

---

Top Contributors

[![adriansuter](https://avatars.githubusercontent.com/u/3974990?v=4)](https://github.com/adriansuter "adriansuter (192 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (28 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")

---

Tags

autoloadoverridephpphp7phpunittestingunit-testingphptestingoverride

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/adriansuter-php-autoload-override/health.svg)

```
[![Health](https://phpackages.com/badges/adriansuter-php-autoload-override/health.svg)](https://phpackages.com/packages/adriansuter-php-autoload-override)
```

###  Alternatives

[phpunit/php-code-coverage

Library that provides collection, processing, and rendering functionality for PHP code coverage information.

8.9k935.9M1.7k](/packages/phpunit-php-code-coverage)[behat/behat

Scenario-oriented BDD framework for PHP

4.0k101.8M2.2k](/packages/behat-behat)[infection/infection

Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.

2.2k28.9M2.4k](/packages/infection-infection)[magento/magento2-functional-testing-framework

Magento2 Functional Testing Framework

15312.0M36](/packages/magento-magento2-functional-testing-framework)[laraveldaily/filacheck

Static analysis for Filament projects - detect deprecated patterns and code issues

11975.6k](/packages/laraveldaily-filacheck)[php-code-archeology/php-code-archeology

Static analyzer for PHP project archeology. Calculates various metrics for your codebase.

825.2k](/packages/php-code-archeology-php-code-archeology)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
