Search code examples
laravelunit-testingmockery

Laravel Cache testing issue


I'm trying to the the following piece of code:

public function remember(string $key, \Closure $callback, int $ttl = null): mixed
{
   return \Cache::remember($key, $ttl, $callback);
}

with:

public function testRememberWhenTimeoutIsSet(): void
{
    \Cache::shouldReceive('remember')
        ->once()
        ->with(\Mockery::on(function ($key, $ttl, $callback) {
            return $key === 'key' && $ttl === 123 && is_callable($callback);
        }))
        ->andReturn('any-thing');

    $this->assertEquals(
        'any-thing',
        $this->service->remember('key', function () {}, 123)
    );
}

But it keeps giving me the following error:

Mockery\Exception\NoMatchingExpectationException : No matching handler found for Mockery_2_Illuminate_Cache_CacheManager::remember('key', 123, object(Closure)). Either the method was unexpected or its arguments matched no expected argument list for this method

Objects: ( array ( 'Closure' => array ( 'class' => 'Closure', 'identity' => '#3e713b47f2e6096de32a4437ee0381ff', 'properties' => array ( ), ), ))

The error goes away if to completely remove with block. Any ideas?


Solution

  • You can consider the code below to work well:

    Cache::shouldReceive('remember')
        ->once()
        ->with('key', 123, \Closure::class)
        ->andReturn('any-thing')
    ;
    

    with method in your case doesn't need a CLOSURE matcher but only a list of expected arguments.