Help us understand the problem. What is going on with this article?

Laravel7のユニットテストで、base_path()などのヘルパー関数が使えない問題

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```でデフォルトで生成されるファイルの中身を変更することができます。

shrft
ウェブエンジニア歴: 約10年 laravel,vuejsが得意です。 その他: java,html,css,php,react,ruby ウェブサイト、ウェブサービスの開発の相談受け付けています。 ご相談はtwitterからどうぞ。
https://twitter.com/it_shiro
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away