Laravel5.7: 単体テストの例


以前の記事my_locale_urlというヘルパー関数を作りました。
この関数は、日本語から英語へ表示を切り替えるために?lang=enのようなパラメータを追加したURLを返します。
今回はこのヘルパー関数の単体テストを作ります。

親記事

Laravel 5.7で基本的なCRUDを作る - Qiita

テストを生成する

readouble.com: テストの生成と実行

PowerShell
# テストファイルを生成
> php artisan make:test HelpersTest --unit

# デフォルトのテストが通ることを確認
> composer test -- --filter='HelpersTest'

テストを記述する

tests/Unit/HelpersTest.php
    /**
     * my_locale_url() のテスト
     *
     * @return void
     */
    public function testMyLocaleUrl()
    {
        // 指定したページへ移動 (実在しないURLでもOK)
        $this->get('https://foo.com:8080');

        // ヘルパー関数を実行し、加工されたURLを取得する
        $actual = my_locale_url('ja');

        // 期待と実際が同じであることを確かめる
        $this->assertEquals('https://foo.com:8080/?lang=ja', $actual);

        // テスト2回目
        $this->get('http://bar.info:9999/?lang=ja');
        $actual = my_locale_url('en');
        $this->assertEquals('http://bar.info:9999/?lang=en', $actual);

        // テスト3回目
        $this->get('https://baz.io/posts?lang=en&page=23');
        $actual = my_locale_url('ja');
        $this->assertEquals('https://baz.io/posts?lang=ja&page=23', $actual);
    }

その後、composer test -- --filter=HelpersTestを実行します。

(補足) テスト内でページを移動する方法

Requestファサードはモックできない

テスト対象のヘルパー関数ではRequest::fullUrlを使って現在のページのURLを取得しています。
テストではこの値を取得できないので、何らかの対処が必要です。
しかし、Requestファサードのモックは禁じられています。

Note: Requestファサードをモックしてはいけません。代わりに、テスト実行時はgetやpostのようなHTTPヘルパメソッドへ、望む入力を引数として渡してください。

readouble.com: ファサード (モック)

無理やりRequest::shouldReceive('fullUrl')と記述してテストを実行すると、下記のように警告されます。

BadMethodCallException: Method shouldReceive does not exist.

HTTPヘルパメソッドとは?

公式ドキュメントに従って「HTTPヘルパメソッド」を使うしかありません。
この「HTTPヘルパメソッド」とは、TestCaseクラスのメソッドのことのようです。
Laravel API: TestCase

TestCaseクラスは全てのテストに継承されているので、テストの中で$this->get('/posts/23')のように記述することでページを移動できます。
公式ドキュメントでも下記のように説明しています。

getメソッドはアプリケーションに対して、GETリクエストを作成します。

readouble.com: HTTPテスト

getだけでなく、上のAPIリファレンスにもあるとおり、post, put, deleteなどあらゆるリクエストを作成できるようです。

(余談) visitメソッドはLaravel5.3まで

getメソッドを使えばいいと知らずにページを移動する方法を探していた時、visitメソッドを使っている例を見つけました。
ただ、これはLaravel5.4では廃止されたようです。
代わりに、通常のページ移動ではgetを、ブラウザでのページ移動ではブラウザテストのLaravel Duskを使います。
また、5.3までのvisitメソッドを使いたい場合はComposerでlaravel/browser-kit-testingを追加します。
Stack Overflow: laravel - acceptance test method visit undefinied