ロケット発射システムをコードで作成しながら test doubles について理解を深めるW/Sです。
下記の仕様に沿ってロケット発射システムを作成していきましょう。
ロケット発射システムには仕様がいくつかあり、1つずつ確実に仕様確認をするとなると、
開発過程で何発も本物のロケットを発射しなければ開発ができません。
開発のために何発も本物のロケットを発射してたら勿体無いし、万が一不具合が起きたりしたら大変です。
そこで Test Doubles が登場します!
本物のロケットに代わって Test Doubles を使用することで、本物のロケットを発射せずに
機能を一つずつ確実に仕様確認(テスト)できます。
Test Doubles を用いてロケット発射システムのコードを書くことで、
「Stub」「Dummy」「Spy」「Mock」「Fake」それぞれの役割について理解していきましょう!
まずはこのREADMEでそれぞれの内容を読んだ上で、どのようなテストが書かれているかを確認してください。
そして、test doublesを使ってテストが通るようにコードを実装していきます。
rocketLauncher は天気APIに依存しており、その返り値によって挙動が変わります。
このままでは本物のAPIを叩いてしまうので、レスポンスで時間がかかったり、安定したテストができません。
そこで、WeatherRepository の Stub(天気の返り値を固定するもの)を使って、テストできるようにしましょう。
- 天気APIが「晴れ」という結果を返した場合、true が返る。
- 天気APIが「雨」の結果を返した場合、false が返る。
スタブのテストでは、launchメソッド が boolean の値を返す仕様にしていましたが、本来は
RocketLauncherImpl が Rocket というオブジェクトに対して何かしらの操作を与えた結果、
ロケットが発射されるべきです。
そこで、ロケットを発射するときは、Rocket と一緒に Auth(認証情報) を渡し、通っていれば
Rocket のfireメソッド を呼ぶようにします。
ただ、本物の Rocket の fireメソッド を呼んでしまうと、本物のロケットが発射されてしまいます。
また、RocketLauncherImpl の launchメソッド には返り値がありません。
Dummy(使うとエラーを出すもの)を使用して、認証が通らなかった場合には発射されないことを確認しましょう。
- 発射装置の認証が通らなかった場合、ロケット点火ロジックが呼ばれない。
Dummy では、ロケットが発射されていないことのテストしかできませんでした。
今度は、認証状態に応じてロケットが 発射されること・されないこと をどちらもテストで確認したいです。
Spy(ロケットの点火ロジックが 呼ばれたか・呼ばれていないか を記録するもの)を使ってテストしてみましょう。
- 発射装置の認証が通った場合、ロケット点火ロジックが呼ばれる。
- 発射装置の認証が通らなかった場合、ロケット点火ロジックが呼ばれない。
認証が通らなかった場合、ロケットの発射を中止する機能(abort)が追加されました。
そのため、fire と abort、それぞれのメソッドの呼び出し状況をテストしたいです。
まず、SpyRocket を使ってテストを書いてみましょう。
Spy を使ってテストを書くと、リファクタリングの必要性があることに気づきます。
リファクタリングの結果、Spy に アサーション を含む事になりました。
言い換えると、Spy は Mock(自己検証するSpy)にリファクタリングされた事になります。
今度は、MockRocket を使ってテストを通るようにしてみましょう。
- 発射装置の認証が通った場合、ロケット点火ロジックが呼ばれること&無効化ロジックが呼ばれない。
- 発射装置の認証が通らなかった場合、ロケット点火ロジックが呼ばれないこと&無効化ロジックが呼ばれる。
認証サーバーでのログインが必要になった場合について考えてみましょう。
認証サーバーを使うには、会社のセキュリティー部門との打合せや、手続き等、リードタイムが長くなりがちです。
このままでは、それがブロッカーとなりプロジェクトが進みません。
そこで、Fake の役割をするフェイク認証サーバーを使って、認証サーバー以外の部分を進めていきましょう。
フェイク認証サーバーでは、ユーザーIDを渡すと認証済なら ユーザー情報 を、未認証なら undefined を返します。
ただし、Fake にはロジックが含まれるため、Fake に対してのテストも必要となります。
- Fake認証サーバーが正しく動作する。
- 認証されたユーザーが実行した場合、ロケット点火ロジックが呼ばれる。
- 認証されていないユーザーが実行した場合、ロケット点火ロジックが呼ばれない。