PHPackages                             tomb1n0/guzzle-mock-handler - 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. [HTTP &amp; Networking](/categories/http)
4. /
5. tomb1n0/guzzle-mock-handler

ActiveLibrary[HTTP &amp; Networking](/categories/http)

tomb1n0/guzzle-mock-handler
===========================

1.7(1y ago)363.2k—8%2[4 issues](https://github.com/tomb1n0/guzzle-mock-handler/issues)2MITPHPPHP ^7.1|^8.0

Since Jan 27Pushed 1y ago1 watchersCompare

[ Source](https://github.com/tomb1n0/guzzle-mock-handler)[ Packagist](https://packagist.org/packages/tomb1n0/guzzle-mock-handler)[ Docs](https://github.com/tomb1n0/guzzle-mock-handler)[ RSS](/packages/tomb1n0-guzzle-mock-handler/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (18)Used By (2)

Guzzle Mock Handler
===================

[](#guzzle-mock-handler)

[![Latest Version on Packagist](https://camo.githubusercontent.com/657f6a0fc965a001d818b1829f3ac57947df76f4bec7a43f0a05bfcc60534c24/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f746f6d62316e302f67757a7a6c652d6d6f636b2d68616e646c65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tomb1n0/guzzle-mock-handler)[![Total Downloads](https://camo.githubusercontent.com/0ca418b62cbe830134ee29cca51e25a451cdb2b65764c2a9f6164bfbb750157a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f746f6d62316e302f67757a7a6c652d6d6f636b2d68616e646c65722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tomb1n0/guzzle-mock-handler)

When testing third party APIs it is often challenging to mock them in a way that's simple and declarative. This package aims to help make this process simpler by providing a custom handler for guzzle that has router-like behaviour, rather than relying on the responses being popped off the stack in any particular order.

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

[](#installation)

You can install the package via composer:

```
composer require tomb1n0/guzzle-mock-handler
```

Usage
-----

[](#usage)

### Basic Example

[](#basic-example)

```
use GuzzleHttp\Client;
use Tomb1n0\GuzzleMockHandler\GuzzleMockHandler;

// Create a new instance of the mock handler
$handler = new GuzzleMockHandler;

// Create a new mock response for '/login', returning ['key' => 'value'] in the body.
// By default responses expect a GET verb, and return a 200 response.
$loginResponse = (new GuzzleMockResponse('/login'))->withBody([
    'key' => 'value'
]);

// Tell the handler that we're expecting this response
$handler->expect($loginResponse);

// Create a new Guzzle Handlerstack, passing in our custom handler
$stack = HandlerStack::create($handler);

// Finally, create the guzzle client, passing our stack in
$guzzle = new Client(['handler' => $stack]);

$response = $guzzle->get('/login');

// A normal guzzle response object
$response->getStatusCode(); // == 200
json_decode((string) $response->getBody()); // == ['key' => 'value']
```

### Request Assertion

[](#request-assertion)

Sometimes it is useful to perform assertions on the request that returned your response. Maybe you have a class that logs in to a third party API, and you want to assert the username and password were sent through correctly.

```
$handler = new GuzzleMockHandler;
$loginResponse = (new GuzzleMockResponse('/login'))
    ->withMethod('post')
    ->assertRequestJson([
        'username' => 'tomb1n0',
        'password' => 'correct-horse-battery-staple'
    ]);
    // NOTE: If you only care about the username in this case, you can pass in a key as the second parameter to assertRequestJson like so:
    /**
     * ->assertRequestJson('tomb1n0, 'username');
     **/

$handler->expect($loginResponse);

$stack = HandlerStack::create($handler);
$guzzle = new Client(['handler' => $stack]);

// Just before the response is actually sent back to guzzle, our handler will assert the request JSON is corect.
$response = $guzzle->post('/login', [
    'json' => [
        'username' => 'tomb1n0',
        'password' => 'correct-horse-battery-staple'
    ]
]);
```

Note: You can also perform the exact same assertions using `->assertRequestHeaders()`, this will allow you to ensure API requests contain a `X-API-KEY` header or similar.

### Custom Assertions

[](#custom-assertions)

Asserting the body or headers might not be enough, so we allow you to call `->withAssertion()`, passing you the request and response objects, so you can perform your own assertions:

```
$handler = new GuzzleMockHandler;
$loginResponse = (new GuzzleMockResponse('/login'))
    ->withMethod('post')
    // if you want to perform multiple assertions, you can call ->withAssertion multiple times.
    ->withAssertion(function(RequestInterface $request, ResponseInterface $response) {
        $this->assertEquals('super-secure-key', $request->getHeader('X-API-KEY'));
    });

$handler->expect($loginResponse);

$stack = HandlerStack::create($handler);
$guzzle = new Client(['handler' => $stack]);

$guzzle->post('/login');
```

### Asserting Order

[](#asserting-order)

Sometimes it is useful to assert API calls were made in the correct order. Maybe you have to call `/login` before you fetch `/users` for example. This is achieved by giving a name to your responses, then asserting the order after your calls have been made.

```
$handler = new GuzzleMockHandler;
$loginResponse = (new GuzzleMockResponse('/login'))->withMethod('post');
$usersResponse = new GuzzleMockResponse('/users');

$handler->expect($loginResponse, 'login-response');
$handler->expect($usersResponse, 'users-response');

$stack = HandlerStack::create($handler);
$guzzle = new Client(['handler' => $stack]);

$guzzle->post('/login');
$guzzle->get('/users');

// Performs a assertsEquals behind the scenes, as the handler keeps track of the order calls were made in.
$handler->assertCalledOrder([
    'login-response', 'users-response'
]);
```

### Only allowing responses to be called once

[](#only-allowing-responses-to-be-called-once)

Sometimes you might want to only allow an endpoint to be called once in your tests - this can be achieved by calling `->once()` on your response object.

```
$handler = new GuzzleMockHandler;
$loginResponse = (new GuzzleMockResponse('/login'))
    ->withMethod('post')
    ->once();

$handler->expect($loginResponse);

$stack = HandlerStack::create($handler);
$guzzle = new Client(['handler' => $stack]);

$response = $guzzle->post('/login'); // successfull

$response = $guzzle->post('/login'); // ResponseNotFound exception is thrown, "No response set for post => /login"
```

### Testing

[](#testing)

```
composer test
```

Credits
-------

[](#credits)

- [Tom Harper](https://github.com/tomb1n0)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

PHP Package Boilerplate
-----------------------

[](#php-package-boilerplate)

This package was generated using the [PHP Package Boilerplate](https://laravelpackageboilerplate.com).

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance16

Infrequent updates — may be unmaintained

Popularity34

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 94.7% 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 ~104 days

Recently: every ~168 days

Total

14

Last Release

585d ago

Major Versions

0.6 → 1.02021-01-31

PHP version history (3 changes)0.1PHP ^7.1

1.1PHP &gt;=7.1

1.2PHP ^7.1|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/0a38ae99b48bbe724ca5d9589e6a55b48511f5300822aab97fd05f5601e0a97a?d=identicon)[tomb1n0](/maintainers/tomb1n0)

---

Top Contributors

[![tomb1n0](https://avatars.githubusercontent.com/u/11994391?v=4)](https://github.com/tomb1n0 "tomb1n0 (18 commits)")[![chadanuk](https://avatars.githubusercontent.com/u/234815?v=4)](https://github.com/chadanuk "chadanuk (1 commits)")

---

Tags

tomb1n0guzzle-mock-handler

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/tomb1n0-guzzle-mock-handler/health.svg)

```
[![Health](https://phpackages.com/badges/tomb1n0-guzzle-mock-handler/health.svg)](https://phpackages.com/packages/tomb1n0-guzzle-mock-handler)
```

###  Alternatives

[spatie/crawler

Crawl all internal links found on a website

2.8k16.3M52](/packages/spatie-crawler)[omniphx/forrest

A Laravel library for Salesforce

2724.4M8](/packages/omniphx-forrest)[akamai-open/edgegrid-client

Implements the Akamai {OPEN} EdgeGrid Authentication specified by https://developer.akamai.com/introduction/Client\_Auth.html

482.5M6](/packages/akamai-open-edgegrid-client)[muhammadhuzaifa/telescope-guzzle-watcher

Telescope Guzzle Watcher provide a custom watcher for intercepting http requests made via guzzlehttp/guzzle php library. The package uses the on\_stats request option for extracting the request/response data. The watcher intercept and log the request into the Laravel Telescope HTTP Client Watcher.

98239.8k1](/packages/muhammadhuzaifa-telescope-guzzle-watcher)[onesignal/onesignal-php-api

A powerful way to send personalized messages at scale and build effective customer engagement strategies. Learn more at onesignal.com

34170.2k2](/packages/onesignal-onesignal-php-api)[ory/hydra-client-php

Documentation for all of Ory Hydra's APIs.

1710.8k](/packages/ory-hydra-client-php)

PHPackages © 2026

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