Laravelのセッションに関するテストでSession name cannot be emptyが出て落ちる場合の対応

軽い気持ちでcomposer updateしたらテストが落ちて、その調査と暫定対応をしたのでメモ。

エラーログ

PHPUnit\Framework\Exception: [2017-12-04 00:44:41] testing.ERROR: Session name cannot be empty, did you forget to call "parent::open()" in "Symfony\Component\HttpFoundation\Session\Storage\Handler\NullSessionHandler"?.

原因

AbstractSessionHandlerの2ヶ月前の変更による。

[HttpFoundation] Make sessions secure and lazy · symfony/http-foundation@55ca8d8 · GitHub

かつ、もう一つ。

テストケースにphpunit@runInSeparateProcessを付けていると落ちる。
ちゃんと原因を追っていないですが、別プロセスゆえにparent::open()parent::destory()がバラバラになっているのかな。分かりませんが。

なんでこのアノテーションを付けているかというと、依存ライブラリのStaticファサードをモックにしたかったから。
PHPUnitで静的(static)メソッドのモック - Qiita

なお StaticMethods をモッククラスとして定義するので、別のテストで StaticMethods を呼ぶと意図しない結果になります。例えば、次のようなテストケースだと test1 の実行時に StaticMethods がモックとして定義されるので test2 のテストは通りません。 @runInSeparateProcess アノテーションを使えば test1 は別プロセスになるので回避できます。

前も@runInSeparateProcessの挙動でハマったから、これ使いたくない。
その場合はStaticファサードをラップするクラスを自分で用意する必要がある。

対応

ちゃんとやっている余裕はないので暫定対応。
上記のコードを読むとsession.use_cookiesを使っていることが分かるので一時的にoffっている。

# これをテストコードの適当なところに書く
ini_set('session.use_cookies', false);

結論

テスト大事。
とはいえ、今回は「テストでしか落ちない」ケースではあるんだけど。