Laravelのテストを書こう


さっそくですが、Laravel のテストコードを書いていきましょう。こんにちは、OGISHIです。

まずテストコードは Tests\TestCase を継承していることが前提です。なので、

$ php artisan make:test SampleTest

としてFeatureテストを作ります。

リクエストを発行して成功することを確認

Laravelではわざわざサーバを立てなくてもリクエストを発行して機能をテストすることができます。便利ですね。

URIの定義は

Route::get('/firstpage', function (Request $request) {
    return view('first_page');
})->name('firstPage');

とします。

SampleTest.php の中身を書きましょう。

public function testFirstPage()
{
    $response = $this->get(route('firstPage'));
    $response->assertStatus(200);
}

これだけで '/firstpage' にリクエストして結果成功であることを確認できます。

assertStatus() の他にも、取得した $response でいろいろなアサーションをすることができます。

  • $response->assertCookie($cookieName, $value);
    指定したクッキーが返されたかどうか
  • $response->assertRedirect($uri);
    指定したURIへのリダイレクトかどうか
  • $response->assertRedirectToSignedRoute($name, $parameters);
    routeに名前を付けているならリダイレクト先をroute名指定で確かめることもできる
  • $response->assertHeader($headerName, $value);
    指定したヘッダが返されたかどうか
  • $response->assertDownload($filename);
    レスポンスがダウンロードかどうかも確認できます
  • $response->assertSee($value, $escape);
    レスポンスに指定した値が含まれているかどうか
  • $response->assertSeeText($value, $escape);
    HTMLタグなどを除いたテキストを対象にすることもできます
  • $response->assertDontSee($value, $escape);
    逆に、指定した値が含まれていないことも確認できます
  • $response->assertJson($value, $strict);
    レスポンスがJSONかどうかを確認できます。$value に指定した値が含まれていることを確認できるのですが、少し癖があるので思ったとおりの結果となるか必ず確認してください。

他にどのようなアサーションができるかは以下のコードをみるとわかります。

vendor/laravel/framework/src/Illuminate/Testing/TestResponse.php

機能クラスをテストする

リクエストした先のコントローラからロジックを実装したクラスを呼び出している場合は、そのクラスのメソッドをモックしてテストします。

例)LogicDomainクラスのexec()メソッドが呼ばれることを確認する

public function testLogicDomain()
{
    $this->mock(LogicDomain::class, function (MockInterface $mock) {
        return $mock->shouldReceive('exec') // 関数 exec が
            ->once() // 1回だけ呼び出され
            ->andReturn(true); // そのとき true を返す
    });

    $response = $this->get($url);
    $response->assertOk();
}

これで実際に exec() 関数を呼び出さず(exec関数の挙動に左右されず)に、確かに1回だけ呼び出されることを確認できます。

exec() 関数が正しく実行されるか確認する

ここでは exec($id) で指定IDのユーザ名が表示されるとしましょう。

URIの定義は

Route::get('/userName/{id}', function(Request $request, LogicDomain $domain, $id){
    return $domain->exec($id);
})->name('userName');

とします。

public function testExecFunction()
{
    // テストデータとしてUserを3つ作ります。
    // それぞれ id が 1, 2, 3 となる想定です。
    User::factory(3)->create();
    // リクエストします。パラメータは 2 とします。
    $response->get(route('userName'), [2]);

    // 確認のためのデータを取得します。
    $user = User::find(2);

    // レスポンスを確認します。
    $response->assertOk()
        ->assertSee($user->name);
}

このような感じで機能一つ一つを確認するコードを書くことで、途中で仕様が変わって改修したような場合でもテストがロジックの変化に応じて成功/失敗の形で挙動の変化を教えてくれます。テストコードを適切に書いておくと、後々改修が必要なときも副作用を心配せずに心穏やかにプログラムを変更することができますね。

Laravel はその強力なコンテナ機能でクラスまるごとモックすることが簡単にできますので、日頃からテストしやすい構造のプログラムを書くよう心がけると相乗効果でテストも短時間で書けるようになります。

テストコードの書き方やモックについては以下をじっくり読んでくださいね。

HTTPテスト 8.x Laravel  

モック 8.x Laravel 

Mockery:Mockery 1.0 

 

 

  お問い合わせ  - お気軽にお問い合わせください - 

  • 株式会社 パブリックリレーションズ
  • 〒064-0807
  • 北海道札幌市中央区南7条西1丁目13番地 弘安ビル5階
メールでのお問い合わせはこちら

  • この記事をシェアする