BIOGRAPHYREADME2015.12.04LaravelのテストをPHPUnitで書く時にやってる工夫このブログははてなブログからの移行記事です。はじめにこの記事はアイスタイルアドベントカレンダー4日目の記事です。1日目に記事を書いたばかりな気もしますがたぶん気のせいですね。今日はLaravelのテストをPHPUnitで書く際に行ってるちょっとした工夫についてお話します。Laravelのバージョンは5.1、PHPUnitは4.*代を想定しています。テストを書くということみなさんエンジニアであれば当然、テストを書いていると思います。テストを書くことには実に様々なメリットがありますが、僕が特に強く感じているのは以下の2つの点です。後から手を加える時にバグを察知しやすいコードが綺麗になるわたしは新卒1年目なので今年の研修期間2ヶ月で社内向けサービスを作成したのですが、その際にテストの恩恵を大きく感じながら開発を進めていました。開発が進むにつれていくつか苦しいポイントが出てきました。テストを書いててつらいこと今回、アプリの規模が小規模だったので簡易MVCをアーキテクチャとして採用し、サービス、モデルクラスは全てInterfaceに依存。全てサービスコンテナに突っ込むという方法をとっていました。そもそも、その設計自体突っ込みどころが満載なのは置いておくとして、それに対してテストを書いてると以下のつらみが出てきました。Interface継承したモッククラスを作るのがつらいあるクラスの単体テストを書く時、そのクラスが依存している(コンストラクタでタイプヒントしている)のがインターフェースだと、テストの際に渡すインスタンスもそのインターフェースをimplementsしている必要があります。}}これをテストしたくて、Pizzaクラスを生成しようと思うとどこかからCheezeInterfaceを継承したモッククラスを作成する必要があります。Mockeryを使う、もしくはサービスコンテナの中身をバインドして別のモッククラスに差し替えるという2つの方法がありえますが、どちらもインターフェースを継承するために全てのメソッドを実装する必要が出てきます。Interfaceのメソッドを足す/減らす時のテストの修正量が肥大化わたしはモッククラスをMockeryでなく、テストファイル内にインターフェースを継承させたモッククラスを作りサービスコンテナの中身をそれに差し替えるという手法をとっていました。この方法が個人的には楽でしたし、後から見ても読みやすいのですがテストの量が増えてくるとインターフェースメソッドの引数を1つ直すだけでファイルを5個修正しなきゃいけない、というようなことが頻発しました。それだけ依存関係が出ている時点でリファクタリングのタイミングでありつつも、何を修正するにも修正箇所が増えてつらい事態となっていました。解決策これらの問題を解決するために僕がしているちょっとした工夫をご紹介します。インターフェースを継承したモッククラスを親クラスに書いておくLaravelでPHPUnitを使用する際、デフォルトの状態であればtests/TestCase.phpが作成されており、全てのテストクラスはこれを継承してテストを行います。そこでモック用のクラスを作成しておくことで少し記述量を減らすことが可能です。PizzaTest.phpとGratinTest.phpの2つでCheezeInterfaceを継承したクラスが欲しいとします。その場合は以下の様に表現します。}こう書いておくことにより、以下の様な恩恵が受けられます。CheezeInterfaceの実装メソッドが増えた際、修正するのはTestCaseのMockCheezeのみ各テストクラスは必要なインターフェースを継承したモッククラスをextendsし、テストに必要なメソッドのみオーバーライドするこれで少しばかり、テストの修正量や記述量を減らすことができます。まとめ今回学んだこととして、テストコードはアプリのため、自分のためのチェック機構ですが、それを保守したり修正するのも自分たちということを忘れないようにしたいなと思いました。テストで煮詰まるとつい通すことが優先してその場しのぎのゴリ押しテストを書いたりしてしまいますが、それを後から修正する人の気持ちになって、アプリケーションコードと同じように愛を持って、効率よくかけると良いと思います。明日は@kubotak氏により「Riot.jsでSPAを作る」です!お楽しみに!。