Laravel:PHPUnitを使用してテストする際の基本的な実施方法

LaravelPHPUnitを使用してテストする際の基本的な実施方法などをメモします。

LaravelにはPHPUnitが標準で入ってます。なのでインストールする必要はありません。
どんなシステムでもテストは必要になってきますが、まずはPHPUnitでテストする際の基本的な操作方法などを記載します。


testsディレクトリの構成

まずはtestsディレクトリの構成についてです。
最初は下記の構成になっているのですが、サンプルのテストファイルが用意されています。

tests
 ├─ Feature
 │    └─ ExampleTest.php
 │
 ├─ Unit
 │    └─ ExampleTest.php
 │
 ├─ CreatesApplication.php
 └─ TestCase.php

基本的には上記のファイル構成ですが、実際のディレクトリ構成と同じようにディレクトリを作成することも可能です。

例としては下記のような感じになります。

tests
 ├─ Http
 │    └─ Controller
 │            └─ ExampleTest.php
 │
 ├─ Models
 │    └─ ExampleTest.php
 │
 ├─ CreatesApplication.php
 └─ TestCase.php

その際は「phpunit.xml」の内容を変更します。

    <testsuites>
        <testsuite name="Unit">
            <directory suffix="Test.php">./tests/Unit</directory>
        </testsuite>

        <testsuite name="Feature">
            <directory suffix="Test.php">./tests/Feature</directory>
        </testsuite>

        <testsuite name="App">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>
    </testsuites>

上記の例では↓の部分を追加しています。

        <testsuite name="App">
            <directory suffix="Test.php">./tests</directory>
        </testsuite>

これを記述することで「./tests」ディレクトリがテストの対象となります。

 

テストファイルの作成

テストファイルを作成する場合は下記のコマンドを実行します。
すると「Feature」ディレクトリ内にテストファイルが作成されます。

php artisan make:test HogeTest

また、unitのテストを作成する場合は「–unit」をつけて下記を実行。

php artisan make:test HogeTest --unit

上記実行するとベースとなるファイルが作成されます。

 

テスト実行

コマンドから下記を実行することでテストを流すことができます。
注意するのがテスト全体だと複数人で開発をしていた場合は他の方が書いたテストコードまで実行してしまう恐れがあります。
また、ファイル名の指定だと指定した文字列がテストしたいファイル以外のファイル名にも存在する場合、そちらも実行してしまいます。

・テスト全体

./vendor/bin/phpunit

・ファイルパス指定

./vendor/bin/phpunit tests/Feature/ExampleTest.php

・ファイル名の指定

./vendor/bin/phpunit --filter=ExampleTest

 

テストの書き方

上記で作成したテストファイルにtestから始まるメソッドを用意して、テストを記述します。

    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

または、コメントで「@test」をつけることでメソッド名にtestをつけなくてもテストとして実行することが可能です。

    /**
     * @test
     */
    public function BasicTest()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }

 


今回はLaravelPHPUnitを使用してテストする上で、基本的な実施方法などについて記載しました。
テストはプログラムを作成するときは必ず必要になりますので、しっかりテストを書けるように理解しながら進めることが大事だと思います。
また、DBなどが絡んでくる場合などは他にも設定した方がいいものなどありますが、また別の記事で記載したいと思います。

Laravel:Route::resourceの「only」と「except」でリクエストを制限する

Laravelルーティングでは「Route::resource」で指定することがあります。
「Route::resource」を指定するとCRUDのルーティングを1つの定義で行うことが可能になります。

一つ一つルーティングの指定を書いてもいいのですが、場合によっては「Route::resource」で指定した方がソースコードもスッキリし、可読性が上がるかもしれません。

ただ、不要なメソッドもあると思うので、その場合は「only」と「except」を使用し、不要なルーティングを制限することができます。
今回は「Route::resource」を使用した時の「only」と「except」の使用方法についてメモします。


Route::resourceの使い方

Laravelのルーティングの指定は「routes」ディレクトリ内のファイルに記載します。
※下記が例として「routes/web.php」に書いてる場合。

基本的な書き方

Route::resource('photos', 'PhotoController');

ルーティングの内容は下記のようになります。

+-----------+---------------------------+--------------------+------------+
| Method    | URI                       | Name               | Action     |
+-----------+---------------------------+--------------------+------------+
| GET       | /photos                   | photos.index       | index      |
| GET       | /photos/create            | photos.create      | create     |
| POST      | /photos                   | photos.store       | store      |
| GET       | /photos/{photo}           | photos.show        | show       |
| GET       | /photos/{photo}/edit      | photos.edit        | edit       |
| PUT/PATCH | /photos/{photo}           | photos.update      | update     |
| DELETE    | /photos/{photo}           | photos.destroy     | destroy    |
+-----------+---------------------------+--------------------+------------+

次のコマンドを実行すれば現在のルーティングを一覧で表示することができます。
ターミナルからコンテナ内で下記を実行。

php artisan route:list

使わないメソッドに関してはメソッドを消しているとエラーが起きてしまうので、ルーティングを制限しておく必要があります。
その際に「only」と「except」を使用します。

 


「only」で使用するメソッドを指定

「only」で指定した場合、記述したメソッドのみリクエストすることが可能になります。

onlyを使用した場合の例

Route::resource('photos', 'PhotoController', ['only' => ['index','show']]);

上記の例では「index」と「show」のみ許可しています。

+-----------+---------------------------+--------------------+------------+
| Method    | URI                       | Name               | Action     |
+-----------+---------------------------+--------------------+------------+
| GET       | /photos                   | photos.index       | index      |
| GET       | /photos/{photo}           | photos.show        | show       |
+-----------+---------------------------+--------------------+------------+

 

「except」で使用しないメソッドを指定

「except」で指定した場合、記述したメソッド以外のリクエストが可能になります。
なので、除外したいメソッドを記述します。

exceptを使用した場合の例

Route::resource('photos', 'PhotoController', ['except' => ['edit','create']]);

上記の例では「edit」と「create」以外のリクエストを許可している形になります。

+-----------+---------------------------+--------------------+------------+
| Method    | URI                       | Name               | Action     |
+-----------+---------------------------+--------------------+------------+
| GET       | /photos                   | photos.index       | index      |
| POST      | /photos                   | photos.store       | store      |
| GET       | /photos/{photo}           | photos.show        | show       |
| PUT/PATCH | /photos/{photo}           | photos.update      | update     |
| DELETE    | /photos/{photo}           | photos.destroy     | destroy    |
+-----------+---------------------------+--------------------+------------+

 


今回はLaravelルーティングで「Route::resource」を使用した時の「only」と「except」の使用方法について記載しました。
この辺りを理解しておくとルーティングの記述を綺麗にまとめることができると思います。

Laravel:Non-static methodのエラーが発生した時の対応方法

Laravelで「Non-static method」のエラーが発生した時の対応方法をメモします。

このエラーはstaticではないメソッドを呼び出すときに発生します。
Laravelに限らずではありますが。。。

下記に「Non-static method」エラーの説明と対応方法を記載します。


「Non-static method」のエラー内容

実際のエラー内容としては、下記のようにエラーが出力されます。
簡単にいえば「staticではないですよー」ってことですね。

ErrorException: Non-static method App\Models\Hoge::getHoge() should not be called statically

 

「Non-static method」エラーになる原因

例で下記のようにコントローラーからモデルのメソッドを呼び出します。

【Controller】

下記は「Hoge」モデルクラスの「getHoge」メソッドを呼び出しています。

use App\Models\Hoge;

class SampleController extends Controller
{
    public function index()
    {
        Hoge::getHoge();
    }
}

 

【Models】

下記の場合はエラーになってしまいます。
原因はfunctionに「static」が無いからです。

class Hoge extends Model
{
    public function getHoge() {
        // 処理
    }
}

なので「static」があればエラーにならず正常に動作します。

class Hoge extends Model
{
    public static function getHoge() {
        // 処理
    }
}

 

「Non-static method」エラーの対処方法

上記のように「static」付ければ解決することはできますが、モデルを変更できない場合はコントローラー側で下記のように呼び出すとエラーとならずメソッドを呼び出すことができます。

【変更前】

use App\Models\Hoge;

class SampleController extends Controller
{
    public function index()
    {
        $res = Hoge::getHoge();
    }
}

 

【変更後】

use App\Models\Hoge;

class SampleController extends Controller
{
    public function index()
    {
        $model = new Hoge();
        $res = $model->getHoge();
    }
}

このように呼び出すことによって「Non-static methodエラーを解消することができます。

 


今回は「Non-static methodエラーが発生した時の対応方法について記載しました。
以外と忘れてしまうことがあるのでメモします。