- 今までの説明 → テストの可読性、 有用な診断メッセージ
- 今回 → 関係あるコードが壊れてる時だけ失敗させる
この章の趣旨を一言で表すと…
「何が起こるべきなのかを正確に指定せよ。余計なことを一切指定するな」
例: 顧客を検索するためのクラスのモック
null を返してみる → 不正確
- 問題1:「null」が何を意味するのかが分からない
- 問題2: リファクタリングに弱い
解決策: カスタマーが見つからなかった事を指す定数を用意する
シナリオに関連する内容だけチェックする。他はチェックしない。
- 入力と無関係な物
- 他のテストでカバーされている物
返される値が複雑な場合
- 関心のある属性をテストする
- 文字列の場合は興味のある文字列が含まれているかをチェックする
- 構造化されたオブジェクトが必要だというサイン
- 的確にコードを書く事はエクスペクテーションの部分にも当てはまる
- (半分は jMock の機能紹介)
的確なパラメータマッチング
- 例: sniperForItem カスタムマッチャーを引数に使用
アローアンスとエクスペクテーション
- 例: ignoring() と allowing()
- 呼ばれなくても良いという事を示唆する
- 呼ばれた回数を指定する事も出来る(atLeast())
- コラム: クエリにはアローアンス、コマンドにはエクスペクテーション
- コマンド: 副作用がある、何かが変更されることが期待される
- クエリ: 副作用が無い、つまり不要なら呼び出されなくても良い
無関係なオブジェクトは無視する
- jMock はゼロを表すオブジェクトを用意している
- 立て続けにignoring()を使っている場合は新しいオブジェクトとして切り出せるサイン
起動の順序
- jMock は起動順序は基本的に気にしない
- 順序が必要でないのなら気にするべきでも無い
- パラメータのマッチングに使うので全く気にしない訳ではない
- 起動順をチェックする仕組み
- Sequence / inSequence() … 単純に順序を指定する
- States … ステートマシン
- あまりに複雑な起動順チェックは、クラスを分解するべきというサイン
jMock State の威力
- State はテスト対象/ピア/テスト自身の論理的な状態
更に自由なエクスペクテーション
- リフレクションを活用したエクスペクテーションも使える
例: XmlMarshaller アダプター
-
テストに AuctionClosedEvent を使い回している
- これは Xml の永続化には関係無いクラス
-
AuctionClosedEvent が使われない事になった場合
- AuctionClosedEvent 自身が実際にここ以外で使われなくても残る
-
AuctionClosedEvent の構造が変化した場合
- 一部のフィーチャーがテストでカバーされなくなる
-
解決策: テスト用に専用のクラスを用意する
- 本当の問題は何が起こるべきなのかを正確に把握する事とその習慣だと思う。
- これさえクリアすればそれをテストに落とし込むのはそう難しくない
- でもその解決策は書いていない