Skip to content

Commit

Permalink
Merge pull request #359 from saloonphp/feature/global-mock-client
Browse files Browse the repository at this point in the history
Feature | Global Mock Client
  • Loading branch information
Sammyjo20 authored Jan 18, 2024
2 parents e956c73 + 1e0cfe9 commit 1a69816
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 18 deletions.
50 changes: 37 additions & 13 deletions src/Http/Faking/MockClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,17 @@ class MockClient
*/
protected array $recordedResponses = [];

/**
* Global Mock Client
*
* Use MockClient::global() to register a global mock client
*/
protected static ?MockClient $globalMockClient = null;

/**
* Constructor
*
* @param array<\Saloon\Http\Faking\MockResponse|\Saloon\Http\Faking\Fixture|callable> $mockData
* @throws \Saloon\Exceptions\InvalidMockResponseCaptureMethodException
*/
public function __construct(array $mockData = [])
{
Expand All @@ -67,7 +73,6 @@ public function __construct(array $mockData = [])
* Store the mock responses in the correct places.
*
* @param array<\Saloon\Http\Faking\MockResponse|\Saloon\Http\Faking\Fixture|callable> $responses
* @throws \Saloon\Exceptions\InvalidMockResponseCaptureMethodException
*/
public function addResponses(array $responses): void
{
Expand All @@ -82,8 +87,6 @@ public function addResponses(array $responses): void

/**
* Add a mock response to the client
*
* @throws \Saloon\Exceptions\InvalidMockResponseCaptureMethodException
*/
public function addResponse(MockResponse|Fixture|callable $response, ?string $captureMethod = null): void
{
Expand Down Expand Up @@ -238,8 +241,6 @@ public function getLastResponse(): ?Response

/**
* Assert that a given request was sent.
*
* @throws \ReflectionException
*/
public function assertSent(string|callable $value): void
{
Expand All @@ -250,8 +251,6 @@ public function assertSent(string|callable $value): void

/**
* Assert that a given request was not sent.
*
* @throws \ReflectionException
*/
public function assertNotSent(string|callable $request): void
{
Expand All @@ -264,7 +263,6 @@ public function assertNotSent(string|callable $request): void
* Assert JSON data was sent
*
* @param array<string, mixed> $data
* @throws \ReflectionException
*/
public function assertSentJson(string $request, array $data): void
{
Expand All @@ -291,8 +289,6 @@ public function assertSentCount(int $count): void

/**
* Check if a given request was sent
*
* @throws \ReflectionException
*/
protected function checkRequestWasSent(string|callable $request): bool
{
Expand All @@ -315,8 +311,6 @@ protected function checkRequestWasSent(string|callable $request): bool

/**
* Check if a request has not been sent.
*
* @throws \ReflectionException
*/
protected function checkRequestWasNotSent(string|callable $request): bool
{
Expand Down Expand Up @@ -373,6 +367,36 @@ public function findResponseByRequestUrl(string $url): ?Response
return null;
}

/**
* Register a global mock client
*
* This will register a global mock client that is available throughout the
* application's lifecycle. You should destroy the global mock client
* after each test using MockClient::destroyGlobal().
*
* @param array<\Saloon\Http\Faking\MockResponse|\Saloon\Http\Faking\Fixture|callable> $mockData
*/
public static function global(array $mockData = []): MockClient
{
return static::$globalMockClient ??= new static($mockData);
}

/**
* Get the global mock client if it has been registered
*/
public static function getGlobal(): ?MockClient
{
return static::$globalMockClient;
}

/**
* Destroy the global mock client
*/
public static function destroyGlobal(): void
{
static::$globalMockClient = null;
}

/**
* Test if the closure can pass with the history.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Http/PendingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function __construct(Connector $connector, Request $request, MockClient $
$this->method = $request->getMethod();
$this->url = URLHelper::join($this->connector->resolveBaseUrl(), $this->request->resolveEndpoint());
$this->authenticator = $request->getAuthenticator() ?? $connector->getAuthenticator();
$this->mockClient = $mockClient ?? $request->getMockClient() ?? $connector->getMockClient();
$this->mockClient = $mockClient ?? $request->getMockClient() ?? $connector->getMockClient() ?? MockClient::getGlobal();

// Now, we'll register our global middleware and our mock response middleware.
// Registering these middleware first means that the mock client can set
Expand Down
4 changes: 0 additions & 4 deletions tests/Pest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@

use Saloon\Tests\Fixtures\Connectors\TestConnector;

expect()->extend('toBeOne', function () {
return $this->toBe(1);
});

/*
|--------------------------------------------------------------------------
| Functions
Expand Down
60 changes: 60 additions & 0 deletions tests/Unit/GlobalMockClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

use Saloon\Http\Faking\MockClient;
use Saloon\Http\Faking\MockResponse;
use Saloon\Tests\Fixtures\Requests\UserRequest;
use Saloon\Tests\Fixtures\Connectors\TestConnector;

afterEach(function () {
MockClient::destroyGlobal();
});

test('can create a global mock client', function () {
$mockClient = MockClient::global([
MockResponse::make(['name' => 'Sam']),
]);

expect($mockClient)->toBeInstanceOf(MockClient::class);
expect(MockClient::getGlobal())->toBe($mockClient);

$connector = new TestConnector;
$response = $connector->send(new UserRequest);

expect($response->isMocked())->toBeTrue();
expect($response->json())->toEqual(['name' => 'Sam']);

$mockClient->assertSent(UserRequest::class);
});

test('the mock client can be destroyed', function () {
$mockClient = MockClient::global();

expect(MockClient::getGlobal())->toBe($mockClient);

MockClient::destroyGlobal();

expect(MockClient::getGlobal())->toBeNull();
});

test('a local mock client is given priority over the global mock client', function () {
MockClient::global([
MockResponse::make(['name' => 'Sam']),
]);

$localMockClient = new MockClient([
MockResponse::make(['name' => 'Taylor']),
]);

$connector = new TestConnector;
$connector->withMockClient($localMockClient);

$response = $connector->send(new UserRequest);

expect($response->isMocked())->toBeTrue();
expect($response->json())->toEqual(['name' => 'Taylor']);

$localMockClient->assertSentCount(1);
MockClient::global()->assertNothingSent();
});

0 comments on commit 1a69816

Please sign in to comment.