tomb1n0 / guzzle-mock-handler
Installs: 36 991
Dependents: 2
Suggesters: 0
Security: 0
Stars: 3
Watchers: 2
Forks: 2
Open Issues: 4
Requires
- php: ^7.1|^8.0
- guzzlehttp/guzzle: ^6.2|^7.0
- spatie/macroable: ^2.0
Requires (Dev)
- phpunit/phpunit: ^7.0|^8.0|^9.0
README
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
You can install the package via composer:
composer require tomb1n0/guzzle-mock-handler
Usage
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
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
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
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
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
composer test
Credits
License
The MIT License (MIT). Please see License File for more information.
PHP Package Boilerplate
This package was generated using the PHP Package Boilerplate.