エンジニアのひよこ_level10

【毎日更新!】新卒2年目エンジニアブログです! プログラムだけじゃなく、マネジメントとかも書いていきたい!

【Laravel5.6】cacheヘルパ関数で、テストのshouldReceiveが動かない対応【327日目】

結論

cache('key')を使った場合、withの中身を with('key', null)にする。

サンプルコード

public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key', null)
         ->andReturn('value');

    $this->visit('/cache')
         ->see('value');
}

公式ドキュメントがちょっと違う

ファサード 5.6 Laravel

ファサードとヘルパ関数との間に、全く違いはありません

実はちょっと違います。

受け取る引数が異なっているために、該当ファサードをモックしようとすると正しく動かない場合があります。

動かないコード

公式引用 web.php

Route::get('/cache', function () {
    return cache('key');
});

テスト用コード

public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key')
         ->andReturn('value');

    $this->visit('/cache')
         ->see('value');
}

エラー文

Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_0_Illuminate_Cache_CacheManager::get('key', NULL). Either the method was unexpected or its arguments matched no expected argument list for this method

対応

Mockery_0_Illuminate_Cache_CacheManager::get('key', NULL) なので、引数が増えてますね。

withの引数が 'key' のみなので、 with('key', null)にする必要があります。

どうしてこうなるのか

cache関数の実装を見てみます。

    function cache()
    {
        $arguments = func_get_args();

        if (empty($arguments)) {
            return app('cache');
        }

        if (is_string($arguments[0])) {
            return app('cache')->get($arguments[0], $arguments[1] ?? null);
        }

->get($arguments[0], $arguments[1] ?? null);なので、渡す引数が ('key', null)になっています。

検証用コード

    public function testAccessCacheHelper
    {
        Cache::shouldReceive('get')
            ->with('key')
            ->andReturn('value');

        Cache::shouldReceive('get')
            ->with('key', null)
            ->andReturn('value_2');

        dump(Cache::get('key'), cache('key'));
    }

こうすると、値が “value”,“value_2"になります。

感想

これに2時間かけました・・・まさか公式ドキュメントそのままで動かないとは。
ただ、テストコードの理解をするのに良い時間になりました。

もし、間違いがあれば、ご指摘いただきたいです。