[Laravel]phpunitでRequestオブジェクトのmockを作成できない

カテゴリ: 未分類

Laravelでユニットテストをする際、(httpリクエストではなく)共通ライブラリのテストを行いたくて、Requestオブジェクトのモックを作りたい場合があります。

Mockeryを使って普通に作ると以下のうようにすれば良さそうですが、これは正しく動作しません。

use Illuminate\Support\Facades\Request;

class SomeTest extends TestCase
{

    public function testBasic()
    {
        // Requestのモックを作り、header()をコールしたら'hearer-value'を返すようにする
        Request::shouldReceive('header')
            ->once()
            ->andReturn('hearer-value');

        // requestのfeaderをコールしたら'hearer-value'が返るはず... 
        //   (だが、このコードは正しく動かない)
        $value = request()->header('foo');
        $this->assertEquals('hearer-value', $value);
     }
}

実際に実行してみると、以下のようにsetUserResolver()の呼び出しが誤っているいうエラーになります。

$ phpunit

PHPUnit 8.5.8 by Sebastian Bergmann and contributors.

There was 1 error:
Mockery\Exception\BadMethodCallException: 
   Received Mockery_1_Illuminate_Http_Request::setUserResolver(), 
   but no expectations were specified

FacaceがRequestオブジェクトを生成する際に、内部ではsetUserResolver()がコールされています。ですが前述のテストコードではsetUserResolver()のモックを正しく作っていません。これがテストが動作しない理由です。

RequestオブジェクトをMockで作ってはいけないことはLaravelの公式ドキュメントにも記載があります。

You should not mock the Request facade.

Instead, pass the input you desire into the HTTP helper methods 
such as get and post when running your test.

Likewise, instead of mocking the Config facade, 
call the Config::set method in your tests.

Requestファサードをモックしてはいけません。
その代わりテストを実行するときに、getやpostなどのHTTP helper methodsへ望む入力を渡してください。
同様に、Configのファサードをモックする代わりに、テストの中でConfig::set()メソッドを使ってください。

[https://laravel.com/docs/8.x/mocking より]

getやpostのヘルパーメソッドというのは、以下のようなlaravelのPHPUnitで使用できるヘルパメソッドのことで、Tests\TestCaseを継承することで使用できます。

use Tests\TestCase;

class SomeTest extends TestCase
{

    public function testBasic()
    {
        $this->get(...);
    }
}

Amazonでおトクに買い物する方法
AmazonチャージでポイントGET


Amazonは買いもの前にAmazonギフト券をチャージしてポイントをゲットしないと損!

こちらもおススメ

One thought on “[Laravel]phpunitでRequestオブジェクトのmockを作成できない

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です