PHPackages                             michiruf/laravel-http-automock - 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. michiruf/laravel-http-automock

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

michiruf/laravel-http-automock
==============================

Automatically mock http requests when testing

0.3(1mo ago)161.0k↓50%[13 issues](https://github.com/michiruf/laravel-http-automock/issues)MITPHPPHP ^8.2CI passing

Since Sep 14Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/michiruf/laravel-http-automock)[ Packagist](https://packagist.org/packages/michiruf/laravel-http-automock)[ Docs](https://github.com/michiruf/laravel-http-automock)[ GitHub Sponsors](https://github.com/michiruf)[ RSS](/packages/michiruf-laravel-http-automock/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (21)Versions (23)Used By (0)

Laravel Http Automock
=====================

[](#laravel-http-automock)

[![Run Tests](https://github.com/michiruf/laravel-http-automock/actions/workflows/run-tests.yml/badge.svg)](https://github.com/michiruf/laravel-http-automock/actions/workflows/run-tests.yml)[![Latest Version on Packagist](https://camo.githubusercontent.com/7d8a40e5a6a905d8aa8683e5f86faaa77e6fe5bac271469a9f45e86aa1fb31b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d696368697275662f6c61726176656c2d687474702d6175746f6d6f636b2e737667)](https://packagist.org/packages/michiruf/laravel-http-automock)[![Total Downloads](https://camo.githubusercontent.com/0744c5ae94c2e6c96e278736b0f737c1ab735a8184cdcc5aae20a428ea9884a2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d696368697275662f6c61726176656c2d687474702d6175746f6d6f636b2e737667)](https://packagist.org/packages/michiruf/laravel-http-automock)

Automatically record and replay HTTP responses in your Laravel tests. On the first test run, real HTTP requests are made and the responses are saved to disk. On subsequent runs, the saved responses are used instead, no real requests are made. This makes your tests faster, deterministic, and independent of external services. Automock is fully compatible with `Http::fake()`.

Requires PHP 8.2+, Laravel 11+, and [Pest](https://pestphp.com/). Works only with Laravel's [HTTP client](https://laravel.com/docs/http-client).

Quick Start
-----------

[](#quick-start)

### Installation

[](#installation)

```
composer require michiruf/laravel-http-automock --dev
```

Optionally publish the config:

```
php artisan vendor:publish --tag="http-automock-config"
```

### Usage

[](#usage)

Call `Http::automock()` inside your test before executing HTTP requests. Responses will be automatically saved on the first run and replayed on subsequent runs.

```
it('can do stuff with the api', function () {
    Http::automock();
    $response = Http::get('https://api.sampleapis.com/coffee/hot')->json();
    expect($response)->toHaveCount(20, 'There are not 20 hot coffees in the api service');
});
```

For more test examples, see the [example test](./tests/Feature/ExampleUsageTest.php).

### How It Works

[](#how-it-works)

1. You call `Http::automock()` in a test, which registers the recording/replaying handlers
2. When an HTTP request is made:
    - If a mock file exists for that request, the saved response is returned (no real request)
    - If no mock file exists, the real request is made and the response is saved to disk
3. Mock files are stored per-test in a directory structure like: ```
    tests/.pest/automock/TestScope/ExampleTest/it_can_do_stuff_with_the_api/1_GET_4c147242.mock

    ```

Motivation
----------

[](#motivation)

When testing applications that depend on external APIs, you often end up manually capturing response data to feed into `Http::fake()`. This is tedious, especially when services return large or complex payloads. Running real requests in tests ensures your application actually works against live data, but the execution time is high, and maintaining both faked and real test setups creates significant overhead.

Laravel Http Automock removes that burden. On the first run, your tests hit the real APIs and responses are saved automatically. Every subsequent run replays those responses instantly. You get the confidence of real data without the cost of real requests. The concept is similar to snapshot testing, except that instead of persisting the test output, Automock persists the input.

Since mock files live in your repository, Git naturally picks up changes in external API responses which makes it easy to notice when a service changed its behavior while keeping a safe copy of the data.

Configuration
-------------

[](#configuration)

Each feature can be configured via three methods (in order of precedence):

1. **Fluent API**: `Http::automock()->someFeature()` or `Http::configureAutomock()->someFeature()`
2. **CLI**: `./vendor/bin/pest --automock-option`
3. **Config**: `config/http-automock.php` (if published)

Note

`Http::automock()` both enables Automock and returns the instance for fluent configuration. `Http::configureAutomock()` returns the instance without enabling Automock, useful for setting options separately.

### Reference

[](#reference)

In addition to the publishable config `http-automock.php`, you can use these methods to configure Automock:

FeatureFluent APICLI FlagDefaultEnable`Http::automock()``--automock-enabled`offDisable`...->disable()` / `Http::noAutomock()`——Directory—`--automock-directory=...``'.pest/automock'`Extension—`--automock-extension=...``'.mock'`Shared`...->shared()``--automock-shared``false`Shared directory—`--automock-shared-directory=...``'.pest/automock/Shared'`Prettify dir naming`...->prettifyDirectoryNaming()``--automock-prettify-directory-naming``false`File name resolver`...->resolveFileNameUsing(...)``--automock-file-name-resolver=...``'stack'`Headers`...->withHeaders(...)``--automock-headers=...`off / `[]`Renew`...->renew()``--automock-renew``false`Prevent auto renew`...->preventAutoRenew()``--automock-prevent-auto-renew``false`Prune`...->prune()``--automock-prune``false`Prevent real requests`...->preventRealRequests()``--automock-prevent-real-requests``false`Prevent unknown requests`...->preventUnknownRealRequests()``--automock-prevent-unknown-real-requests``false`Skip (URL pattern)`...->skip('pattern', 'alias')``--automock-url-filters=...``[]`Skip GET/POST/...`...->skipGet()`, `...->skipPost()`, etc.——Validate mocks`...->validateMocks()``--automock-validate-mocks``false`Mock HTTP fakes`...->mockHttpFakes()``--automock-mock-http-fakes``false`JSON pretty print`...->jsonPrettyPrint()``--automock-json-pretty-print``true`### Enable / Disable

[](#enable--disable)

Automock is not active by default. It must be explicitly enabled per-test by calling `Http::automock()`. To disable Automock afterward, use `disable()` or `Http::noAutomock()`.

### File Name Resolvers

[](#file-name-resolvers)

Each mock file needs a unique filename so that requests can be matched to their saved responses. File name resolvers control how these filenames are generated from the request properties (URL, method, body, etc.). The default `stack`resolver produces filenames like `1_GET_4c147242.mock` by combining a request counter, HTTP method, and URL hash.

You can switch to a different resolver, combine multiple resolvers, or provide your own logic entirely - either via a named resolver from the config, a closure, or a resolver class instance.

Available resolvers: `stack`, `count`, `http_method`, `url_hash`, `url_subdirectory`, `data_hash`

**Using a named resolver:**

```
Http::automock()->resolveFileNameUsing('url_subdirectory');
// Creates: .../api.example.com/coffee/hot.mock
```

**Using a closure:**

```
Http::automock()->resolveFileNameUsing(fn (Request $request, bool $forWriting) => "TEST-{$request->method()}");
// Creates: .../TEST-GET.mock
```

**Using a resolver class:**

```
Http::automock()->resolveFileNameUsing(new RequestUrlResolver(port: false, removeSlashes: false));
// Creates: .../localhost/coffee/hot.mock
```

**Using resolver with custom arguments:**

```
Http::automock()->resolveFileNameUsingResolverAndArgs(
    RequestUrlResolver::class,
    ['port' => false, 'removeSlashes' => false]
);
```

**Configuring the stack resolver:**

The default `stack` resolver combines multiple resolvers into a single filename, joined by a delimiter. You can configure which resolvers are used and even apply different stacks based on URL patterns. In `config/http-automock.php`:

```
'default_filename_resolver' => 'stack',
'filename_resolvers' => [

    'stack' => [
        'resolver' => \HttpAutomock\Resolver\StackResolver::class,
        'filenameResolvers' => [
            // '*' matches all URLs, use specific patterns to customize per host
            '*' => ['count', 'http_method', 'url_hash'],
        ],
        'delimiter' => '_',
    ],

    // Individual resolvers referenced above
    'count'            => \HttpAutomock\Resolver\CountResolver::class,
    'http_method'      => \HttpAutomock\Resolver\RequestMethodResolver::class,
    'url_hash'         => [
        'resolver' => \HttpAutomock\Resolver\RequestUrlResolver::class,
        'hashMethod' => 'xxh32',
    ],
    'url_subdirectory' => [
        'resolver' => \HttpAutomock\Resolver\RequestUrlResolver::class,
    ],
    'data_hash'        => [
        'resolver' => \HttpAutomock\Resolver\RequestResolver::class,
        'hashMethod' => 'xxh32',
    ],

],
```

With the default stack config above, a filename like `1_GET_4c147242.mock` is produced by joining `count` (1), `http_method` (GET), and `url_hash` (4c147242) with `_`.

You can customize the stack per URL pattern. The first matching pattern wins:

```
'filenameResolvers' => [
    '*api.example.com*' => ['http_method', 'url_subdirectory'],
    '*'                 => ['count', 'http_method', 'url_hash'],
],
```

### File Storage

[](#file-storage)

Configure where and how mock files are stored. **Directory** and **Extension** control the base path and file extension for mock files. These can be configured via CLI flags or in the published config file.

**Shared Directory** stores mocks in a shared location for all tests instead of per-test directories:

```
Http::automock()->shared();
```

**Prettify Directory Naming** cleans up test directory names by removing closure suffixes (e.g. `_Closure_Object`) from Pest's directory naming:

```
Http::automock()->prettifyDirectoryNaming();
```

### Headers

[](#headers)

By default, only response bodies are saved to mock files. If your application logic depends on specific response headers (e.g. `Content-Type`, `X-RateLimit-Remaining`), you can opt in to persisting them.

```
Http::automock()->withHeaders(['Server']);     // Specific headers
Http::automock()->withHeaders();               // All headers
```

### Renewing / Pruning

[](#renewing--pruning)

**Renew** forces Automock to re-fetch responses from the real API even when mock files already exist. The new responses overwrite the existing mock files. This is useful when you know an external API has changed, and you want to update your saved mocks to reflect the current behavior.

```
Http::automock()->renew();
```

**Pruning** deletes all existing mock files for the executed test before running it. Only mock files belonging to that specific test are removed, not mocks from other tests. This ensures you start with a clean slate, removing any leftover mocks from requests that are no longer made by the test.

```
Http::automock()->prune();
```

**Prevent Auto Renew** overrides and disables renewing, pruning, and validation, regardless of their individual settings. This is useful for CI environments where you want to ensure that no real requests are made, while still being able to pass `--automock-renew` during local development without conflicts.

```
Http::automock()->preventAutoRenew();
```

Tip

It would be possible to set up a CI pipeline, that renews and commits responses periodically. Consider using some sort of request prevention on tests where it is crucial to deny.

### Preventing Requests

[](#preventing-requests)

By default, when no mock file exists for a request, Automock makes a real HTTP call and records the response. In some scenarios, especially CI pipelines or destructive operations, you want to guarantee that no real requests are ever made. Automock provides two levels of protection:

**Prevent all real requests** blocks every outgoing HTTP request and throws `PreventedRequestException`. No real requests are made, even if mock files are missing. This is the strictest mode.

```
Http::automock()->preventRealRequests();
```

Note

Avoid setting this as a project-wide default. It prevents Automock from recording new mocks or renewing existing ones. Consider using `preventUnknownRealRequests` or no prevention whenever possible.

**Prevent only unknown requests** is a more flexible alternative. It throws `PreventedRequestException` only for requests that don't already have a mock file on disk. Requests with existing mocks still work, including when combined with `renew()` or `prune()` to re-fetch and update them.

```
Http::automock()->preventUnknownRealRequests();
```

Note

Like `preventRealRequests`, avoid setting this as a project-wide default, it limits Automock's ability to record new requests.

Tip

It is highly recommended to enable one of these options in your CI pipeline to ensure tests never make real HTTP calls unexpectedly.

### Skipping Requests

[](#skipping-requests)

Exclude certain requests from being recorded or replayed. Skipped requests pass through to their normal behavior (real HTTP call or Laravel's `Http::fake()`).

**Skip by URL pattern:**

```
Http::automock()->skip('*example.com*', 'alias');
```

**Skip by closure:**

```
Http::automock()->skip(fn (Request $request) => str_contains($request->url(), 'skip'), 'alias');
```

**Skip by HTTP method:**

```
Http::automock()->skipGet();
Http::automock()->skipPost();
Http::automock()->skipPut();
Http::automock()->skipDelete();
Http::automock()->skipUnlessGet();  // Skip all except GET
```

**Clear skip filters:**

```
Http::automock()->stopSkip();        // Clear all
Http::automock()->stopSkip('alias'); // Clear specific
```

### Validation

[](#validation)

When enabled, Automock makes real HTTP requests even when mock files already exist. Instead of replaying the saved response, it compares the live response against the existing mock file and fails the test if they differ. The mock files themselves are not updated. This is useful for detecting when an external API has changed its response format or data, without permanently overwriting your saved mocks. Can be prevented explicitly by enabling prevent auto-renew.

```
Http::automock()->validateMocks();
```

### Mock HTTP Fakes

[](#mock-http-fakes)

By default, Automock only records responses from real HTTP requests and ignores responses produced by Laravel's `Http::fake()`. When this option is enabled, faked responses are also saved to mock files. This can be useful when you want to extract inline fakes into mock files.

```
Http::automock()->mockHttpFakes();
```

### JSON Pretty Print

[](#json-pretty-print)

When enabled (on by default), JSON response bodies are formatted with indentation in mock files. This makes diffs more readable in version control and makes it easier to inspect saved responses manually.

```
Http::automock()->jsonPrettyPrint();
```

Troubleshooting
---------------

[](#troubleshooting)

### Windows Git long paths

[](#windows-git-long-paths)

It might be recommended / essential to use Git long paths when generating long file names. To do so, execute one of the first 2 commands, then review with the 3rd.

```
git config --global core.longpaths true
git config core.longpaths true
git config --list --show-origin
```

For more information see [here](https://stackoverflow.com/questions/22575662/filename-too-long-in-git-for-windows).

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance74

Regular maintenance activity

Popularity26

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 57.1% 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 ~44 days

Recently: every ~79 days

Total

10

Last Release

56d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/79712a8d56f2fa15f6c02e017a1fa6aebadf833d03a25ee86c34413375e5f621?d=identicon)[michiruf](/maintainers/michiruf)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![michiruf](https://avatars.githubusercontent.com/u/8984363?v=4)](https://github.com/michiruf "michiruf (4 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (2 commits)")

---

Tags

laravelmichiruflaravel-http-automock

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/michiruf-laravel-http-automock/health.svg)

```
[![Health](https://phpackages.com/badges/michiruf-laravel-http-automock/health.svg)](https://phpackages.com/packages/michiruf-laravel-http-automock)
```

###  Alternatives

[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[spatie/laravel-visit

Quickly visit any route of your Laravel app

15614.6k](/packages/spatie-laravel-visit)[christophrumpel/missing-livewire-assertions

This package adds missing livewire test assertions.

149336.0k9](/packages/christophrumpel-missing-livewire-assertions)

PHPackages © 2026

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