Mocking laravel cache helper

Viewed 1393

Using the PESTPHP testing framework, I want to mock Laravel's cache helper but when I try it, I get an error like this:

Method Mockery_2_Illuminate_Cache_CacheManager::remember() does not exist on this mock object`

I want to mock the rememberForever() method but why does the remember() method show in the error message? I also tried to change shouldReceive() to another method, but always the remember() method gets mocked.

Here's my controller code :

public function index()
{
    $groups = cache()->rememberForever('groups', fn() => Group::pluck('id', 'slug'));

    return view('index', compact(
        'groups'
    ));
}

and my test:

it('should return given data on index page', function () {
    /** @var \Tests\TestCase $this */

    $groups = Group::pluck('id', 'slug');

    Cache::shouldReceive('rememberForever')->once()
        ->with('groups', \Closure::class)
        ->andReturn($groups);

    actingAs()->get(route('index'))
        ->assertViewHasAll([
            'groups' => $groups,
        ]);
});

Here is the error shown:

 • it should return given data on index page

  ---


   Mockery\Exception\BadMethodCallException 

  Method Mockery_2_Illuminate_Cache_CacheManager::remember() does not exist on this mock object

  at D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\vendor\mockery\mockery\library\Mockery\Loader\EvalLoader.php:34
     30▕         if (class_exists($definition->getClassName(), false)) {
     31▕             return;
     32▕         }
     33▕
  ➜  34▕         eval("?>" . $definition->getCode());
     35▕     }
     36▕ }
     37▕

  1   D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\vendor\mockery\mockery\library\Mockery\Loader\EvalLoader.php:34
      Mockery_2_Illuminate_Cache_CacheManager::_mockery_handleMethodCall("remember")

  2   D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\database\factories\UserFactory.php:24
      Mockery_2_Illuminate_Cache_CacheManager::__call("remember")


  Tests:  1 failed
  Time:   10.12s

And when using partialMock:

  • it should return given data on index page

  ---

   ErrorException 

  Trying to access array offset on value of type null

  at D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\vendor\laravel\framework\src\Illuminate\Cache\CacheManager.php:327
    323▕      * @return string
    324▕      */
    325▕     public function getDefaultDriver()
    326▕     {
  ➜ 327▕         return $this->app['config']['cache.default'];
    328▕     }
    329▕
    330▕     /**
    331▕      * Set the default cache driver name.

  1   D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\vendor\laravel\framework\src\Illuminate\Cache\CacheManager.php:327
      Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Trying to access array offset on value of type null", "D:\Projects\Framework\laravel\Kuhaku\Kuha
ku-Web\vendor\laravel\framework\src\Illuminate\Cache\CacheManager.php", [])

  2   D:\Projects\Framework\laravel\Kuhaku\Kuhaku-Web\vendor\mockery\mockery\library\Mockery\Loader\EvalLoader.php:34
      Illuminate\Cache\CacheManager::getDefaultDriver()


  Tests:  1 failed
  Time:   5.47s
1 Answers

The rememberForever method doesn't exist on the CacheManager instance you get by using the cache() helper or the Cache facade. Instead it's on the CacheRespository instance, which you can watch with Mockery::spy() to ensure the correct methods are called.

public function testCacheWorks(): void
{
    $cacheRepository = Cache::driver();
    $cacheRepositorySpy = \Mockery::spy($cacheRepository);
    Cache::swap($cacheRepositorySpy);

    // do stuff that writes to the cache

    $cacheRepositorySpy->shouldHaveReceived("rememberForever")
        ->once()
        ->with($cache_entry_key, \Closure::class)
        ->andReturns($some_test_object);
}

Picked this up here: https://github.com/laravel/framework/issues/10803#issuecomment-625261817

Related