Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DerekCaswell's avatar

Mocking the Cache facade not working

I have a method that is using an atomic lock and I would like to create a test for what happens if the lock is taken already. I have the following code in my test:

public function testLockTimeExceptionThrows()
{
    $request = $this->getLicensePurchaseRequest();
    Cache::shouldReceive('lock')->once()->andThrow(new LockTimeoutException());
    DB::partialMock();
    DB::shouldNotReceive('rollBack');

    $this->actingAs($this->user)->postJson("/api/{$this->account->getKey()}/license", $request)
            ->assertStatus(500);
}

When I run the test, however, I get this error:

Mockery\Exception\BadMethodCallException : Received Mockery_1_Illuminate_Cache_CacheManager::driver(), but no expectations were specified

I am using the default array cache driver. Any ideas on why I am not able to mock the Cache facade?

Also, I want to show that the DB::rollBack() is not run. What i have above was a guess but if someone knows how to do that, I would appreciate help with that as well.

0 likes
1 reply
DerekCaswell's avatar

OK, I was able to find a solution that works although I am interested to see if anyone has a better solution. What I came up with was:

public function testLockTimeExceptionThrows()
{
    $request = $this->getLicensePurchaseRequest();

    $limiter = new RateLimiter(Cache::driver());
    $this->swap(RateLimiter::class, $limiter);
    $lock = Mockery::mock(Lock::class);
    $lock->shouldReceive('block')->once()->andThrow(new LockTimeoutException());
    $lock->shouldNotReceive('release');
    Cache::shouldReceive('lock')->andReturn($lock);

    $this->actingAs($this->user)->postJson("/api/{$this->account->getKey()}/license", $request)
        ->assertStatus(500);
}

I ended up not needing to test the DB facade so i was able to take that out.

Please or to participate in this conversation.