最近SymfonyのWebTestCaseが好きになってきた僕です。こんばんわ。
よくある「フォームを表示して値をいれてPOSTする」的なテストでサービスコンテナにモックオブジェクトを登録しても、なぜか差し替わらなくて苦労したので、解決法を共有したいと思います。
まあ、通常であればWebTestCaseでモックを使いたい事はあまりないんですが、外部サービスのAPIを利用してる場合なんかはやっぱりモックが必要になります。
テストのたびにAPI叩くのは流石に・・・。
よくあるフォームを表示して値を入れてPOSTする的なテスト
|
|
よくあるこんなテストケース。
フォームを表示してPOSTするWebTestCaseですね。
これ自体は正常に動作するんですよね。
最初の $client->request('GET', '/admin/hoge/form/');
でリクエストを送った時は、WebTestCaseのcreateClientメソッドで作ったサービスコンテナが使われているんですよね。
でも$client->submit($form);
でリクエストを送った際には違うサービスコンテナが生成されていました。。。
$client->submit($form)でのリクエストの場合のみbootedがfalseになっていた
なぜコンテナが再生成されてしまうのか、ブレークポイントを貼って調べてみたら、どうやら$client->submit($form);
のタイミングでHttpKernelのbootedがfalseになっていました。
おそらくbootedがfalseになるということは、2回目のリクエストを送るタイミングでKernel::shutdown()メソッドが実行されているのではないか?と思い調べてみると、やはりshutdown()メソッドが実行されていました。
なぜshutdownが実行されるのか?
$client->request()
や$client->submit()
するとSymfony\Bundle\FrameworkBundle\Client::dodoRequest()メソッドが実行されるのですが、ここに原因がありました。
この部分のコードをみていただければわかるかと思いますが、1回目の$client->request('GET', '/admin/hoge/form/');
時は$this->hasPerformedRequest
がfalseのためshutdown
が実行されません。
しかしその後$client->submit($form);
すると$this->hasPerformedRequest
がtrueになっているためshutdown
が実行されてしまいます。
shutdownを実行されないようにする
これはすごく簡単で、$client->disableReboot()
を実行すれば良いだけです。
|
|
これでカーネルが再生成されないので、幸せになれます。
まとめ
WebTestCaseではサービスコンテナの再生成が行われないように $client->disableReboot()
しましょう。