web-dev-qa-db-ja.com

hashCode / equals / toStringを単体テストする必要がありますか?

Javaクラスを記述する場合、IDEなどのメソッドを使用してメソッドを生成することは珍しくありません

  • toString()
  • equals()
  • hashCode()

ただし、IDEを使用して生成すると、それらは(SCMの)コードベースの一部になるため、すべての品質測定手段が適用されます。

特に、equalsメソッドとhashcodeメソッドには多くの条件が含まれています。単体テストを作成しない場合、特にテスト対象のクラスがそれほど大きくない場合、コードカバレッジ(行、条件、突然変異)のスコアはかなり低くなります。

一部のカバレッジツールはフィルタリングをサポートします(coberturaなど)、他のツールはサポートしません(jacocoなど)。しかし、カバレッジツールは症状(テストされていないコード)だけを明らかにするので、症状を抑制/無視するかどうかではなく、根本原因に対処する方法を尋ねています。

質問です:これらのメソッドの単体テストを作成する必要がありますか?

  • はいの場合、そうする正当な理由は何ですか?そして賢明なアプローチとは何ですか?
  • いいえの場合、なぜですか?

JAXB pojosやWS-Clientsなど、一般的に生成されたクラスを自動的に生成し、カバレッジ分析から除外することは求めていません。

16
Gerald Mücke

これらのメソッドを生成する場合、おそらくそのためのテストも生成する必要があります;-)

これらのメソッドを手動でテストするのは面倒な場合がありますが、テストで確認したい内容によっては、これらのメソッドもテストする価値がある場合があります。反問:ログステートメントをテストしますか?

それは本当にあなたが達成しようとしていることに依存します。一部は言うでしょう:しない、他の人は言う:する。

そのようなメソッドをテストしないいくつかの理由について考えます:

  • コードが生成され、多くのフィールドが含まれる場合があります。テストすると、さまざまな組み合わせがたくさん発生する可能性があります。これは、書き込み/保守が面倒であり、ジェネレータはすでに十分にテストされていますか? ;-)
  • テストを実装しても価値はありません。 toString()はログまたはデバッガーでのみ使用されるため、気にする必要もありません。
  • 生成されたコードがhashcodeおよびequalsに対して十分安全であると信頼している

そのような方法をテストする理由:

  • 結果が期待どおりであることを確認する
  • これらのメソッドを再生成しても、以前のメソッド実装の使用法を壊さないようにする必要がある
  • ロギングのほかにtoString()-メソッドを使用し、特定のものがそこに表示されないようにします。 Hulkが述べたように、ログに特定のものが表示されないようにすることもできます。

しかし、これらはかなり作り上げられました。最後のプロジェクトでは、toString()equalsまたはhashCodeをテストすることはほとんどありませんでした。

それはすべて、次のようになるかもしれません:コードをどれだけ安全にしたいか、そしてそれがあなた(またはあなたのビジネスや顧客;-)にとってどれだけの価値があるか。

14
Roland

IDE生成されたhashCode/equalsの問題は、オブジェクト自体との同期が取れなくなる可能性があることです(たとえば、新しいフィールドを追加した場合)。そのため、hashCodeとequalsのテストを作成することをお勧めします。

もちろん、これらを手動で書くのは最適ではありません。 EqualsVerifier プロジェクトなどの自動化ツールを使用して、これらをワンライナーにすることができます。

toStringは、定義されたコントラクトがないため、別の獣です。より良いデバッグ体験を得るためにtoStringを使用する場合、私はそれをテストせず、カバレッジ計算から削除します。

8
Karel Petranek

はい、これらすべてをテストします。自動生成されるため、テストは必要ありません。簡単に新しいフィールドを追加して、equals /ハッシュコードの再生成や文字列の作成を忘れる人もいます。

文字列へのテストは、おそらく最も論争の的になるものですが、アプリケーションにログインしている場合は特に必要だと思います。

他の人がすでに示唆しているように、 EqualsVerifier は、等号とハッシュコードをテストするためのおそらく最良のアプローチです。

ToStringメソッドのテストについては、 ToStringVerifier を試してください。テストは次のように簡単です。

@Test
public void testToString() {
    ToStringVerifier.forClass(User.class)
                  .withClassName(NameStyle.SIMPLE_NAME)
                  .verify();
}
1

これらの方法はそれ自体では役に立ちません。これらのクラスをコレクションで使用しない場合(HashSet/HashMapなど)、またはこれらのクラスインスタンスが等しいかどうかを確認しない場合は、単体テストは必要ありません。そして、この場合、@ ByeByeが提案したように、それらを生成するプラグインを無効にします。

ただし、実際にそれを行う場合は、単体テストが必要です。不適切な実装がアプリケーションの障害や不適切な動作を引き起こす可能性がある場合-この実装は単体テストでカバーする必要があります。

0
esin88