makeコマンドでユニットテストを作成すると非常に便利ですね。
php artisan make:test MySampleTest --unit
ただこのコマンドで作成したクラスのではbase_path()やfactory()などのヘルパー関数が利用できません。
ユニットテストを実行すると、以下のように怒られてしまいます。
1) Tests\Unit\MySampleTest::testExample
Error: Call to undefined method Illuminate\Container\Container::basePath()
原因は、テストクラスがフレームワークを読み込んでいないからです。
以下のようにlaravelのTestcaseクラスを読み込むようにすれば問題が解消します。
変更前
use PHPUnit\Framework\TestCase;
class MySampleTest extends TestCase
{
変更後
use Tests\TestCase;
class MySampleTest extends TestCase
{
これはバグですか? 仕様ですか?
GithubのIssueをみたところこれは仕様のようです。
ユニットテストを高速に実行するために、意図的にframeworkの設定を読み込まないようにしているそうです。
I believe unit tests should be as fast as possible so any external influences that decrease their speed should be avoided
(ユニットテストはできる限り早く実行できるべきです。そのため、速度を落とす外部の影響はさけるべきです。)
ヘルパー関数を使う場合はFeatureテストを使えばいいとも言っています。
でもやっぱりユニットテストでもヘルパー関数を使いたい! どうにかして!
make:testコマンドを実行するたびに自分でuse Tests\TestCase
に書き換えるのは面倒ですね。
laravel7以降では、make:testコマンドで生成されるテンプレートをカスタマイズすることができます。
この機能を利用して初めからPHPUnit\Framework\TestCase
ではなくTests\TestCase
が読み込まれるようにしましょう。
make:test --unit コマンドで生成されるテンプレートを変更する
まずは以下を実行
php artisan stub:publish
上を実行するとプロジェクトルートディレクトリ配下にstubs
というディレクトリが作成されます。
その下にtest.unit.stub
というファイルがあるのでこのファイルを書き換えればtest:make --unit```でデフォルトで生成されるファイルの中身を変更することができます。