1 つの複雑な (テストが難しい) パブリック メソッドを持つユーティリティ クラス (データなし) があるとします。乱数生成を使用し、大きな配列のデータを返します。ただし、小さなプライベート メソッドで実装すると、すべてのプライベート メソッドを簡単にテストできるため、全体を簡単にテストできます。アプリケーションの観点からは、big メソッドのみをパブリックにする必要があり、もう一方はプライベートにする必要があります。それでも、プライベート メソッドをテストすると、クラスのテストが容易になります。この問題にどのようにアプローチすればよいですか?
5 に答える
場合によっては、乱数を生成したり、大きな配列を返したり、その他の楽しいことをしたりすることは、単一のユーティリティ クラスが複数のことを担当することを意味します。つまり、代わりにもっと多くのクラスが必要です。単一のクラス (単一のメソッド!) が非常に複雑であることは、設計が悪いことを示している場合があります。しかし、従うべき黄金律は 1 つではありません。
プライベート メソッドをテストする必要があることは、警告サインです。これは、大きくて複雑な方法に対する解決策ではありません。単一責任原則(SRP)を考慮すると、機能を小さなクラスに抽出することが解決策です。SRP では、クラスは実際には 1 つのことだけを行うべきであると述べています。
乱数の生成、配列の処理、および楽しいことは、少なくとも 3 つの別々のことであり、別々に行う必要があります。
サブパートをテストできない単一のブラックボックス アルゴリズムとしてメソッドを残すか、クラスを分離するためにできるだけ多くの責任を外部化するかは、状況によって異なります。
再利用される可能性が高いサブパーツがある場合は、それらを除外することをお勧めします。他のレイヤーやハードウェアと通信するサブパーツがあるかもしれません - 同じことです。
それはすべて、これらの小さなサブメソッドが何をするかによって異なります。コンテキストなしではわかりません。
クラスのパブリックAPIのみをテストすることには非常に強い議論があります。メソッドのシグネチャを変更しない限り、単体テストを変更する必要がなく、変更によって何も破損していないことが検証されるため、コードのリファクタリングがはるかに簡単になります。
そうは言っても、プライベートメソッドをテストすることが理にかなっている場合があります(ただし、これは例外であり、ルールではありません)。一部のテストフレームワーク(MSTestなど)では、この目的のためだけにプライベートメンバーにアクセスできますが、他のフレームワーク(nUnitなど)では、アクセスする必要があるとは思わないため、アクセスできません(.Netの場合はそれほど多くはかかりません)。ただし、アクセスを許可する独自のリフレクションクラス/メソッドを作成します)。
プライベートメソッドをテストする場合は、前述のように、後のリファクタリングを検証するためにパブリックテストが必要になるため、完全なパブリックメソッドもテストするようにしてください。
プライベートメンバーをテストすると、常にテストが脆弱になります。プライベートメソッドをテストする場合、テストは実装の詳細に依存します。実装の詳細は変更される可能性があり、頻繁に変更されます。そもそもそれらを非公開にした理由は、ソフトウェアの他の部分に影響を与えることなくそれらを変更できるようにしたいからです。推測:プライベートを公開すると、リフレクションの「ブラックマジック」のみを使用している場合でも、テストはソフトウェアの一部であるため、公開することになります。
パブリックAPIの機能が多すぎるため、またはプライベートメソッドが非常に重要であるために、実装の詳細をテストする必要があると思われる場合は、コードをリファクタリングし、プライベートメンバーをパブリッククラスとして抽出してテストする必要があります。テストもソフトウェアの一部であるため、使用するコードに「通常の」アクセス権を持っている必要があることを忘れないでください。
これらの(そうではない)プライベートメソッドを公開できないことに固執している場合、おそらく外部ユーザー/コードがそれらにアクセスできるようにすることを恐れて、これらのクラスを内部(C#)またはパッケージプライベートにすることでこれらのクラスへのアクセスを制限できます(Javaの場合)、テストでコードの内部を表示します。
いずれにせよ、あなたのコードはテストされるべきではないか、(もっと)公開されるべきであるように思われます。