privateメソッドはテストを書かなくて良い?

職場のチームで、spring bootを使ったコードを書いている。チームには若手が比較的多く、それほどコーディング経験が豊富でない人もいるチームである。当然単体テストを書くことは必須としていて、良く言われている通り、「privateメソッドは単体テスト不要」ということになっている。

しかし、これをただ鵜呑みにしてはいけないと感じている。

良く見るのが、複雑なprivateメソッドの呼び出しをまとめたpublicメソッドのテスト。

半ば組み合わせ爆発を起こしているような複数条件を多数網羅していて、テストコードの理解や修正が非常に大変なもの。このケースは非常に多く、単純に責務の分割が不十分なまま実装し、privateメソッドはテストしないルールを鵜呑みにしてしまった結果、このようになったのだと思われる。
その結果、単純な変更のテストすらまともに書かれなくなり、単体テストを普通に書けば起きえないような初歩的な不具合を出したのを見たことがある。

そしてもう1つが、上記を避けたいがために、結局無理やりにリフレクションを使ったprivateメソッドのテスト。しかし、これは最後の手段。自分たちが自由にプロダクションコードを書ける状況なので、ほとんどの場合は別の方法を考えるべきだろう。

これらについて、どう考えるべきか、しばらく答えが出せなかった。

しかし最近「Clean Code」を読んでいて1つ確信したことは、テストしやすい粒度のpublicメソッドがある状態が正しいはずだということ。

クラスやメソッドの責務を分離して一つ一つを小さくする。単体テストを書きたくなるようなprivateメソッドはおそらく別のクラスのpublicメソッドになることが多いはず。

ほかにも、t-wadaさんの記事

やはり、その通りのことが書かれている

■別クラスのパブリックメソッドとする

プライベートなメソッドのテストを書きたいということは、実はテスト対象の責務が多すぎることを示唆している場合があります。テストがどうしても書きたい場合は、その責務はテスト対象のプライベートな振る舞いではなく、他の誰かのパブリックな振る舞いなのでしょう。テスト対象のプライベートメソッドを「クラスの抽出」や「メソッド/関数の移動」を使って、テスト対象のコラボレータのパブリックメソッドとして抽出し、普通にパブリックメソッドとしてテストしましょう。

t-wadaさんのブログ

■テスト対象の可視性を(やや)上げる

例えば Java では、同一のパッケージからのみアクセスできる可視性があり(正式名称ではありませんが「パッケージプライベート」と呼ばれます)、テストを同一パッケージに配置することでテストからアクセスできるような設計を行うことがあります。

t-wadaさんのブログ

やはり、自分たちのチームの場合だと、上記を見直すことが有効そう。

コメント

タイトルとURLをコピーしました