Skip to content

Cached requests ignore fixture changes in tests #513

@tovitch

Description

@tovitch

Description

When using cached requests with fixtures in tests, the cache persists even when MockClient fixtures are changed between test runs, causing tests to receive cached responses instead of the updated mock responses.

This happens because MockClient::destroyGlobal() clears the mock client but doesn't clear the caching layer, so the second fixture is ignored.

Expected Behavior

When using MockClient::fixture() or MockClient::global() in tests, fixtures should bypass or automatically disable caching to ensure tests use the mocked responses consistently.

Actual Behavior

Cached responses are returned even when different fixtures are set up, requiring manual cache disabling with disableCaching() in the constructor.

Code Example

// This fails because second run uses cached response from first fixture
test('cache ignores fixture changes', function () {
    // First run with fixture A
    MockClient::global([
        MyRequest::class => MockResponse::fixture('fixture-a'),
    ]);
    $response1 = $connector->send(new MyRequest()); // Uses fixture-a
    
    // Second run with fixture B - cache prevents this from working
    MockClient::destroyGlobal();
    MockClient::global([
        MyRequest::class => MockResponse::fixture('fixture-b'), 
    ]);
    $response2 = $connector->send(new MyRequest()); // Still uses fixture-a from cache!
});

Current Workaround

Add cache disabling in the request constructor:

public function __construct()
{
    if (app()->runningUnitTests()) {
        $this->disableCaching();
    }
}

Suggested Solution

  1. Option A: Fixtures should automatically bypass caching
  2. Option B: MockClient::global() and MockClient::destroyGlobal() should clear relevant caches when fixtures are set up
  3. Option C: Add a method like MockClient::globalWithoutCache() for testing scenarios

Environment

  • Saloon version: v3.14.0
  • Laravel version: 12.24.0
  • PHP version: 8.4

Related

This is related to the global mock client introduced in #359, where destroyGlobal() was added to prevent leaky tests, but the caching layer isn't cleared alongside the mock client.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions