単体テストの考え方/使い方を読んだ。読んでよかった。

読んでよかった

book.mynavi.jp

評判通りよかった

  • そっかーなるほどなぁ。面白いなぁ。と思うことがいろいろあった
  • とはいえ、著者の主張全てに同意というわけではなく「著者はそう考えるんだな。自分は違う考えだな」と考えさせられる部分もいくつかあった

苦手な部分もあった

  • 古典学派とロンドン学派に分けて話を展開しているのはあまり好きじゃないなと思いながら読んだ
  • 定理やマトリクスに当てはめて話を展開する部分があって、いくつかは無理やりだったり話をややこしくしていたりするように自分は感じた。そういう部分は苦手だなぁと思いながら読んだ

というのが全体の感想。内容はとてもよかったし、苦手な部分もそれはそれで考えさせられたので、読んでよかった。ってことでパラパラめくりながらメモを書いていこう

あらためて意識したい2本

「第4章 良い単体テストを構成する4本の柱」の中の2本が、当たり前のことではあるけどあらためて上手にまとめられていて、常に意識しておきたいなと思った

リグレッションに対する保護

  • ふるまいが変わったらテストが失敗すること
  • テストの際に実行されるプロダクションコードが多いほど価値がある
  • 複雑な部分に対するテストのほうが価値がある

「取るに足らないコードに対してはテストをする価値がほとんどない」っていうの、言われてみたらそうだなぁって思った。別のところで「質の悪いテストケースを作成するくらいなら、そのようなテストケースをまったく作成しないほうがよい」ってのも、言われてみたらそうだなぁって思った

リファクタリングへの耐性

  • 実装の詳細を変更しても、ふるまいが同じならテストが失敗しないこと

ここの偽陽性の説明は、ちょっと話をややこしくしてるように感じながら読んだ。ただ、この観点はめちゃいい。実装に対するテストじゃなくてふるまいに対するテストがいいよね

ふるまいに対する単体テスト

この「ふるまいに対するテスト」のために、複雑なコードを分解する指針を示してくれている。これ分かりやすい

複雑なコードの分解

「第7章 単体テストの価値を高めるリファクタリング」の、複雑なコードを分解して2つのタイプに落とし込む話。なるほどなぁ面白いなぁって思った。次の2つのタイプに分解する

  • 複雑さや重要さはあまりないが、協力者オブジェクトが多い
  • 複雑・重要、だけど協力者オブジェクトは少ない

そうすると、前者がアプリケーションサービス(コントローラ)、後者がドメインモデル(ビジネスロジック)になる

(ところで、この章でやってることってリファクタリングじゃなくてコード改善だよなと思いながら読んだ )

リポジトリをドメインモデルに渡さない

協力者オブジェクトとのやりとりはコントローラの担当なので、DBアクセスはコントローラーで実行して、その結果をパラメータとしてドメインモデルに渡す。そうすることでドメインモデルからDBへのアクセスをなくす。って話を読んで、へーって思った

自分はRepositoryインターフェースをドメインモデルに渡すのはアリだと思っているから、次にそういう設計をするときがあったらRepositoryをどうするといいかちょっと疑ってみよっと

ただ、この著者の方針のおかげでドメインモデルが外部の依存から切り離されて単体テストが実行しやすくなっているのは、なるほどなぁという気持ち

ドメインモデルのふるまいに対して単体テストを書く

「システム内コミュニケーションは実装の詳細」だから、ドメインモデルの中のそれぞれのクラスに対して単体テストを書くんじゃなくて、ドメインモデルのふるまいに対して単体テストを書く。ふむふむ

システム内コミュニケーションにはモックは使わない。使うと実装の詳細を把握していることになってしまうからね。ふむふむ

と、そういう風に2つのタイプに分解してドメインモデルを外部の依存から切り離すと、単体テストはドメインモデルのテストということになる

統合テスト

上記の流れでドメインモデルに単体テストを書くと、単体テストに対してはモックを使う必要がない。モックを使うのは「システム間コミュニケーション」を含む動作確認の場合。つまり、統合テストの場合

DBは実装の詳細

DBは外部依存ではあるが、他のシステムから利用されていなければ、実装の詳細とみなせる。だから、統合テストではモックせずにDBにつないでテストをするべきという話

僕もDBはつないでテストをするのが好きだけど、それが「実装の詳細とみなせる」からというのは、確かに言われてみたらそっかー

管理下にない外部依存はモックする

管理下にない外部システムとのやりとりの部分はモックにして、統合テストを作成する。分かりやすいなー

感想

コードをコントローラとドメインモデルに分けて、ドメインモデルを単体テストで確認して、コントローラを統合テストで確認する。か。

だから、「コードをコントローラとドメインモデルに分けて」をどう実現できるか、ってところが大切だよな。

次にそういう設計をするときがあったら、この本のことを思い出しながら試行錯誤してみようと思った。

今日書いたこと以外にも、いろいろと面白い話が書かれていて、それもよかった。

読んでよかった。