#StackBounty: #unit-testing #laravel-5 #mocking Is a Cache mock called more than once when browser-testing?

Bounty: 50

I’m trying to cover the following:

Uncovered line

Resulting in Uncovered Method

I’m using the following test code:

public function test_it_deletes_a_patient()
{
    // ...

    $cacheKey = vsprintf('%s.%s', [$this->doctorUser->id, 'backoffice.stats.patientsTotalCount']);
    Cache::shouldReceive('has')->with($cacheKey)->once()->andReturn(false);
    Cache::shouldReceive('increment')->with($cacheKey, -1)->once()->andReturn(true);

    $response = $this->json('DELETE', route('patients.destroy', $this->patient), ['confirmation' => 'ELIMINAR']);

    // ...
}

That triggers the following controller code:

public function destroy(Patient $patient, Request $request)
{
    $this->authorize('delete', $patient);

    $confirmation = $request->get('confirmation');

    if ($confirmation != 'ELIMINAR') {
        return response()->json(['success' => false]);
    }

    logger()->info("Deleting Patient Profile PATIENT_ID:[{$patient->id}]");

    $patient->delete();

    $this->updatePatientsCount(-1);

    return response()->json(['success' => true]);
}

protected function updatePatientsCount($amount = 1)
{
    $key = vsprintf('%s.%s', [auth()->user()->id, 'backoffice.stats.patientsTotalCount']);
    if (Cache::has($key)) { // I want to mock for testing this
        Cache::increment($key, $amount); // I want to mock for testing this
    }
}

After test run I get:

alariva@trinsic:~/fimedi$ t --filter=test_it_deletes_a_patient
PHPUnit 7.3.1 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 6.53 seconds, Memory: 26.00MB

There was 1 failure:

1) TestsBrowserBackofficePatientsTest::test_it_deletes_a_patient
Unable to find JSON fragment
["success":true]
within
[{"exception":"Mockery\Exception\NoMatchingExpectationException","file":"/home/alariva/fimedi/vendor/mockery/mockery/library/Mockery/ExpectationDirector.php","line":92,"message":"No matching handler found for Mockery_0_Illuminate_Cache_CacheManager::has('2056e535e689ab723b3f44831b488f05f7fb8b90'). Either the method was unexpected or its arguments matched no expected argument list for this methodnn","trace":[{"class":"App\Http\Middleware\Language","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Barryvdh\Debugbar\Middleware\InjectDebugbar","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\Auth\Middleware\Authenticate","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Illuminate\Cookie\Middleware\EncryptCookies","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php","function":"handle","line":151,"type":"->"},{"class":"Il

What I interpret after a couple of tests, is that it looks like once I mock Cache it is being called by some middlewares before reaching the tested block, so since those called methods are not mocked, the test fails because it does not know what to answer for those middleware calls.

Imagine I could successfully mock all the calls before getting to the tested codeblock, I would be able to make it reach. But that’s not the way to go over it.

How can I mock Cache and avoid failure due to previous Cache calls that I’m not testing?

Sidenote: if I try to disable middlewares ($this->withoutMiddleware();) I get an AccessDeniedHttpException

alariva@trinsic:~/fimedi$ t --filter=test_it_deletes_a_patient
PHPUnit 7.3.1 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 12.95 seconds, Memory: 24.00MB

There was 1 failure:

1) TestsBrowserBackofficePatientsTest::test_it_deletes_a_patient
Unable to find JSON fragment
["success":true]
within
[{"exception":"Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php","line":201,"message":"This action is unauthorized.","trace":[{"class":"App\Exceptions\Handler","file":"/home/alariva/fimedi/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php","function":"render","line":83,"type":"->"},{"class":"Illuminate\Foundation\Exceptions\Handler","file":"/home/alariva/fimedi/app/Exceptions/Handler.php","function":"render","line":65,"type":"->"},{"class":"Illuminate\Foundation\Exceptions\Handler","file":

Maybe I can cherry-pick middlewares to disable?


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.