KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

[RSpec] テストが書きやすいコードは良いコード


matsuyama01

お疲れ様です。松山です。

今回はmodelと、そのユニットテストを用いて、テストを書きやすくしたいと考えて行くうちにmodelが綺麗になっていく様子を解説したいと思います。

### 先ずは、ふざけたmodelとテストコードを用意して、徐々に機能追加していきます。

### 和名にも対応してみましょう。

### もぅ外出しのファイルに持っちゃいましょう。

### 例外処理と、オレオレ詐欺も追加します。

### リファクタリング
ここまで、テストのグリーンを保ちつつmodelに機能を追加しました。ここで、Ore.firstnameメソッドの処理を列挙してみます。

* ore.ymlを読み込みRuby Objectに変換する
* 引数lastnameで検索しfirstnameを返す
* もしlastnameが’オレオレ’だったら詐欺を疑う
* その他の場合、'(Unknown)’を返す
* ore.ymlへのアクセスに失敗した場合、メッセージを出力し正常終了する。
* その他エラーの場合、異常終了する

結構な頑張り屋さんになりました。ここでポイントとなるのは、次の点でテストコードが書きにくいということです。

* このメソッド名にしてはいろいろやりすぎている
* INとOUTが散在していて分かりにくい
* 2つのrescueに到達するのが難しい
* パッと見、if elseで何がしたいのか分かりにくい
* ダサい

なので、以下の方針でリファクタリングを行います

* 処理ごとにメソッドを分ける
* 1つのメソッドが負う責任をシンプルにする
* if elseは、その目的を直感的に表すメソッド名にして切り出す
* AメソッドがBメソッドを呼び出す場合、「Bメソッドを呼んだ」ことのみ確認する

すると以下のコードになりました。

テスト内容は次の通りです。

Ore.firstname

* lastnameがore.ymlに存在しない場合、怪しもうとするところまで確認

Ore.load_file

* ore.ymlの正常な読み込みを確認
* 引数がnilだった場合の異常系処理にてメッセージが出力されないこと、エラーのraiseを確認
* 引数が存在しないファイルパスだった場合は、メッセージが出力されること、エラーがraiseされないことを確認

Ore.怪しむ

* 詐欺かも

### まとめ
以上です。如何だったでしょうか。ついでになりますが、後で直すと分かっていても最初からテストを書くことは重要であることも表現できたと思います。
このように、RSpecはプロダクトコードを読みやすく、またメンテしやすいよう我々を導いてくれるイイ子です。

では、また。

 

【関連記事】
MSXとKONAMIさん
MSXとKONAMIさん(その2)
MSXとKONAMIさん(その3)
[RSpec][VCR] WEB API呼び出しのテストをstubしてみる
[RSpec][VCR] WEB API呼び出しのテストをstubしてみる(その2)
[RSpec][VCR] WEB API呼び出しのテストをstubしてみる(その3)