Symfony Advent Calendar 2019 4日目の記事です。
昨日はtamakiiさんの Docker for Mac でも快適な Symfony 開発環境を作りたい でした!
皆さんは再利用可能なバンドルを作ったことはありますか?
Symfony2時代からSymfonyに触れている方は、アプリケーションの機能を置く場所としてのバンドルは多数開発したことがあると思います。
再利用可能なバンドルとは、モノリシックなアプリ内に置く機能の分類としてのバンドルではなく、複数のアプリケーションから composer require
して使われるバンドルという意味です。
オープンソースの便利なバンドル、 FOSUserBundle
や SonataAdminBundle
なんかがそうですね。オープンソースにしなくても、社内で開発する複数のアプリケーションに共通する機能を再利用可能なバンドルとして開発すると非常に便利です。コピペコードも減って精神的にもとても楽になります。
そもそも再利用可能なバンドルのファンクショナルテストはどうするか
弊社開発部ブログに過去記事があります
https://tech.quartetcom.co.jp/2016/12/19/functional-testing-syfony-bundle/
ファンクショナルテストが無いと、バンドル導入時に受け入れ側のアプリケーションでバンドルの機能に対してテストを書かないと安心して使えないので、テストできるようになっているSymfonyにはホントに助けられています。
フレームワークとしての振る舞いの変更やサービス定義のテストであれば、この過去記事の内容で十分なのですが、問題は再利用可能なバンドルにコントローラアクションを作った場合です。
この場合、Kernelだけを差し替えてもアクションのテストを書くことができません。
再利用可能なバンドルのコントローラアクションのテスト
再利用可能なバンドル内のコントローラアクションに対してファンクショナルテストを書くためには、まず下記のような内容で Tests/Functional/config/routes.yml
を設置します。
※ AcmeDemoBundleのところは実際に開発中のバンドルの名前を入れてください。
_my_actions:
resource: "@AcmeDemoBundle/Resources/config/routing.yml"
次に、 Tests/Functional/config/config.yml
に、設置したroutes.ymlを読み込む設定を追加します。
framework:
router:
resource: "%kernel.root_dir%/config/routes.yml"
これで準備は完了です。
自分のバンドルのファンクショナルテスト用の KernelTestCase
を使い、 static::createClient()
ではなく self::$container->get('test.client')
によって KernelBrowser
を取得することで、普通のアプリケーション内のバンドルを開発するときと同様に、コントローラアクションに対するファンクショナルテストを書くことができます。
おまけ: コントローラに対してDIしているとき(Symfony4+)
Symfony4
以上を使っていてコントローラクラスに対してSymfonyのDI機能で依存を注入させたいときは、Controllerを public: true
でサービスとして登録する必要があるので注意してください。
一見DIできないように見えてエラーと戦うのですが、 ContainerControllerResolver クラスのコードを読むとわかります。
まとめ
以前 Twitterで呟いた とおり、カルテット開発部では「フレームワークはどうでもいい」のですが、「なんでも良い」わけでなくドメインのコードを邪魔しないフレームワークとしては、いまのところSymfonyが最強だと思っています。
※ 個人の意見です(笑)