問題
自動検出対応のパッケージを新たにcomposer require
で入れたんだけど、何故かそのパッケージを使ったテストが通らない。しかし該当の処理をphp artisan tinker
で手で実行するとちゃんと動くという謎の現象にでくわしました。
原因
自動検出されたパッケージの情報はbootstrap/cache/packages.php
, bootstrap/cache/services.php
にキャッシュされていてもしあればここに書かれた情報で動きます。composerで新しいパッケージをインストールしたときは自動的にphp artisan package:discover
を行う設定がcomposer.json
に書かれているのでそれによって更新されます。
ところが、このファイルの場所は環境変数で変更することが出来て、phpunit実行時はphpunit.xml
に以下のような記述があって変更されています。
<server name="APP_SERVICES_CACHE" value="bootstrap/cache/services.phpunit.php"/>
<server name="APP_PACKAGES_CACHE" value="bootstrap/cache/packages.phpunit.php"/>
そのため、phpunitの初回実行時にいったん作られはするのですが、その後は更新されません。このせいで新しいパッケージのサービスプロバイダの初期化がphpunitから実行するときだけ行われず動作がうまくいっていなかったわけです。
対処
bootstrap/cache/services.phpunit.php
, bootstrap/cache/packages.phpunit.php
を削除してやれば次にphpunitを実行すると新しい状態になります。
そもそもphpunitのときだけこれらのキャッシュファイルを別のものに変更する必要が普通はないような気もするので上記の設定をphpunit.xml
からバッサリ削除して後顧の憂いを絶つのもいいかもしれません。
さらに、これは問題だと思うのでissue出そうかと調べたら、なんと既に去年の9月頃に直っていました。([6.x] Remove testing bootstrap extension #5107) その少し前に作ったプロジェクトなんですよね。
ただ、フレームワーク本体と違ってvendorの外にあるファイルはcomposer update
などでは更新されず最初にプロジェクトを作ったときのままになるのが普通なので、この状態になっているプロジェクトも多いのではないかと思います。気をつけましょう。