Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8.x] Clear recorded calls when calling Http::fake() #40194

Merged
merged 2 commits into from
Dec 30, 2021
Merged

[8.x] Clear recorded calls when calling Http::fake() #40194

merged 2 commits into from
Dec 30, 2021

Conversation

mateusjunges
Copy link
Contributor

@mateusjunges mateusjunges commented Dec 29, 2021

This PR aims to clear the $recorded array on Illuminate\Http\Client\Factory class.

Background

Currently, i'm creating a test to ensure that i will never login to an api while i still have a valid bearer token. The token management is handled with cache, with the token being stored in cache for now() + $access_token['expires_in'] seconds. It works fine, but in my tests, in order to ensure that i'll only call the login api the token is already expired, i mock the login response using Http::fake(), freeze the time (using spatie's test-time package), then call the login api, receive and store the token in cache. Then, i call Http::fake() one more time (to forget recorded calls) and call the api again, with time freezed and token in cache yet. Now, as i haven't called the login api (due to token being in cache), i want to assert that nothing was sent using Http::assertNothingSent(), but the problem is: The $recorded property are never cleared when i call fake, and the assertion fails.

Here's some code snippets to illustrate what i'm explaining:

TestTime::freeze();

Http::fake([
    '*/auth/oauth/v2/token' => Http::response([
        'token_type' => 'Bearer',
        'access_token' => $accessToken = '2XzMDjRfl76ZC9Ub0wnz4XsNiRVBChTYbJ',
        'expires_in' => 420,
        'scope' => 'my-scopes-here'
    ])
]);

$token = MyServiceClass::login()

$this->assertIsString($token);

$this->assertEquals("Bearer $accessToken", $token);

$this->assertEquals("Bearer $accessToken", Cache::get('login-token');

TestTime::addSeconds(419);

Http::fake();

$token = MyServiceClass::login()

$this->assertEquals("Bearer $accessToken", $token); // It works, because my service returns the token from cache.

$this->assertEquals("Bearer $accessToken", Cache::get('login-token');

Http::assertNothingSent(); // It fails, because $recored wasn't cleared.

Solution

As a proposed solution, i've added a call to clear the $recorded array within the fake method:

public function fake($callback = null)
{
    $this->record();

    $this->recorded = [];

@taylorotwell taylorotwell merged commit f55fee2 into laravel:8.x Dec 30, 2021
@mateusjunges mateusjunges deleted the fixes/http-fake branch December 30, 2021 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants