首页 > 解决方案 > 模拟 laravel 缓存助手

问题描述

使用PESTPHP 测试框架,我想模拟 Laravel 的缓存助手,但是当我尝试它时,我得到一个这样的错误:

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

我想模拟该rememberForever()方法,但为什么该remember()方法会显示在错误消息中?我也尝试更改shouldReceive()为另一种方法,但该remember()方法总是被嘲笑。

这是我的控制器代码:

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

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

和我的测试:

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,
        ]);
});

这是显示的错误:

 • 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

并且在使用 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

标签: phplaravelphpunitmockery

解决方案


通过使用帮助程序或外观获得rememberForever的实例上不存在该方法。相反,它在实例上,您可以观察它以确保调用正确的方法。CacheManagercache()CacheCacheRespositoryMockery::spy()

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);
}

在这里选择了这个:https ://github.com/laravel/framework/issues/10803#issuecomment-625261817


推荐阅读