【问题标题】:Unable to mock Cache::put() facade in Laravel无法在 Laravel 中模拟 Cache::put() 外观
【发布时间】:2019-01-11 22:36:03
【问题描述】:

我正在尝试模拟 Cache::put() 外观。但这给了我一个错误。我尝试了不同的方法,但无法弄清楚。

public function testGetAllFromDatabase()
{
    $industry = new Industry();

    Cache::shouldReceive('has')
        ->once()
        ->with('industries.all')
        ->andReturn(false);

    Cache::shouldReceive('put')
        ->with('industries.all', '', 0)
        ->andReturn(true);

    $this->industryMock
        ->shouldReceive('all')
        ->once()
        ->andReturn(array_reverse($this->industries));

    $this->app->instance(Industry::class, $this->industryMock);

    $industryRepository = new IndustryRepository();
    $all = $industryRepository->all();
    dd($all);
    $this->assertContains( $this->industries[2], $all);
}

但是当我执行它时,会发生以下错误。

$ vendor/bin/phpunit
PHPUnit 7.2.7 by Sebastian Bergmann and contributors.

...E                                                                4 / 4 (100%)

Time: 3.76 seconds, Memory: 12.00MB

There was 1 error:

1) Tests\Unit\RepositoriesTests\IndustryRepositoryTest::testGetAllFromDatabase
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Cache_CacheManager::put('industries.all', object(Illuminate\Database\Eloquent\Collection), '1440'). Either the method was unexpected or its arguments matched no expected argument list for this method

Objects: ( array (
  'Illuminate\\Database\\Eloquent\\Collection' =>
  array (
    'class' => 'Illuminate\\Database\\Eloquent\\Collection',
    'properties' =>
    array (
    ),
  ),
))

F:\development\consulting.local\src\vendor\mockery\mockery\library\Mockery\ExpectationDirector.php:92
F:\development\consulting.local\src\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php:223
F:\development\consulting.local\src\app\Repositories\IndustryRepository.php:30
F:\development\consulting.local\src\tests\Unit\RepositoriesTests\IndustryRepositoryTest.php:81

我尝试了很多方法,但无法修复它。谢谢。

【问题讨论】:

  • put 是用 industries.all 调用的,但也是一个集合和 1440 作为参数 2 和 3,因此与您指定的 '', 0 不匹配。如果您不关心参数 2 和 3,请为它们使用 $this->anything()
  • @apokryfos: 你是说 Cache::shouldReceive('put') ->with('industries.all', $this->anything(), $this->anything()) - >andReturn(true);
  • 是的,尽管这适用于PHPUnit's test doubles。对于Mockery,您可能需要改用\Mockery::any()
  • 谢谢,成功了。

标签: laravel phpunit laravel-facade


【解决方案1】:

由于它可能对其他人有所帮助,Laravel's facade 包含允许与 Mockery 测试替身进行交换的辅助函数

这意味着当您使用shouldReceive 时,您可以将它与任何Mockery expectation 链接起来,例如在这种情况下,如果您不关心可以使用的某些参数:

Cache::shouldReceive('put')
    ->with('industries.all', \Mockery::any(), \Mockery::any())
    ->andReturn(true);

【讨论】:

    【解决方案2】:

    如果它对其他人有帮助,最好指出 您可能不想要模拟 Cache,而是实际使用真正的 Cache。

    那是因为它是一个仅供测试的缓存:

    当通过 vendor/bin/phpunit 运行测试时,Laravel [....] 会在测试时自动配置会话和缓存到阵列驱动程序,这意味着测试时不会保留会话或缓存数据。
    @987654321 @


    请注意,与 OP 的测试不同,您可能需要遵循 Laravel 关于您的测试类的指导,扩展他们的 TestCase 以获得行为,例如

    use PHPUnit\Framework\TestCase;
    
    class ExampleTest extends TestCase
    

    【讨论】:

      猜你喜欢
      • 2014-02-17
      • 2016-04-04
      • 2017-07-01
      • 2022-01-04
      • 1970-01-01
      • 2013-06-22
      • 2015-10-26
      • 2020-09-11
      • 2012-07-12
      相关资源
      最近更新 更多