voidメソッドの単体テスト


13

アプリケーションのバグを修正するために、postLoginという名前の既存のメソッドに呼び出しを追加することにより、という名前のメソッドを変更しましたgetShoppingCart

コード

protected void postLogin() {
  getShoppingCart();
}

ただし、単体テストを作成する最適な方法が何であるかはわかりませんpostLogin

アプローチ1

Mockitoのverifyを使用して、メソッドが呼び出されたことを確認します。

verify(mock).getShoppingCart();

アプローチ2

ユーザーのショッピングカートの値を取得して、メソッド呼び出しの副作用をテストします。

AssertNotNull(user.getShoppingCart());

1つのアプローチは他のアプローチよりも優れていますか?


1
テストを理解しやすくし、コードをクリーンに保ちます。あなたがテスト設計が不明な場合、それはCOULDまた、コード設計がオフになっていること徴候です。これらの質問をしていることを確認してください:「なぜそのメソッド呼び出しを追加するとバグが修正されるのですか?これがこのバグを修正する正しい方法ですか?」
カレブ

8
getShoppingCart()メソッドに副作用がない限り、メソッドが呼び出されることをテストする必要はありません。副作用がある場合、getXXX()メソッドは慣習的にべき等であるため、実際に名前を変更する必要があります。
ジュール

@Jules getNextValue?おそらく、誰かが「ゲッターと呼ばないで、名前をnextValue」に変更できますが、getNext以前に使用されたことはあります。おそらく、より良い例は電子を表すオブジェクトでしょう。電話しgetPositionたらどうなりますか?またはさらに悪いことにgetPosition(); getVelocity();
アーロン

回答:


18

私は通常、方法2を好みます。

どうして?postLoginシステムの状態を変更したいのですが、これをどのように達成するか(および内部的にどのメソッドを呼び出すか)は実装の詳細にすぎないため、単体テストでは何も想定しません。そのため、最終状態を確認するだけでテストを実施することをお勧めします。


4

getShoppingCartをinitializeShoppingCartのようなものに変更します。メソッドの目的は、メソッドの動作を確認する必要なく、メソッドのユーザーにいくつかの驚くべき動作を引き起こす可能性のある副作用を引き起こすことなく、それを読む人に明確にする必要があります。

getShoppingCartが別のクラスにあり、すでにユニットテスト済みの場合、アプローチ1を使用します。既にテスト済みのものを再度テストする必要はありません。この場合、getShoppingCartが適切に機能することを確認し、postLoginから呼び出されることのみを保証したいので、将来誰かがこの呼び出しを削除すると、テストは失敗します。

getShoppingCartがそれ自体ではテストできないプライベートメソッドである場合、アプローチ2を使用して、postLoginが呼び出されたときにgetShoppingCartの目的の機能が期待どおりに実行されるようにします。


1

副作用のある関数呼び出し(voidまたはnot)をテストする場合、副作用が発生するだけでなく、副作用(システム出力または状態の変化)が望ましいものであることをテストするのが最も完全です。


1
これは事実ですが、発生する副作用の詳細は他のモジュールの内部状態の一部である可能性があり、それらの詳細を確認することで、テストをモジュールだけでなく、それはテストですが、他のモジュールでもあり、詳細が変更される可能性がある場合、脆弱なテストにつながる可能性があります。モジュール間のインターフェイスのモックは、この問題の防止に役立ちます。
ジュール

0

設計については説明しませんが、ユニットテストは、ドメイン内での仕事に関係なく、どのメソッドが技術的に行われるか、つまりメソッドが何をするかをテストするため、最初のアプローチに進みますpostLogin。技術的に呼び出すgetShoppingCardのでgetShoppingCard、実際に呼び出しgetShoppingCardているテストする必要があります、それが何をするかをテストするための別のテストを作成し、副作用がある場合はその新しいテスト内でそれをチェックします。


0

postLoginにバグがあります。そのため、最初にすべきことは、予期される情報セットなしでpostLoginを呼び出すと「失敗」する単体テストを作成することです。

上記のアイデアから、提案された2の別の選択肢は、ショッピングカートに関する情報をパラメーターとして注入することです。正しい情報がない場合は、未チェックの例外をスローします。これにより、正確な詳細がなければ、メソッドは運命づけられることが明確になります。

これには、今すぐpostLoginを呼び出しているクライアントがショッピングカート情報を渡すために必要な小さな変更が必要になります。私には、これらが結合されていることがわかりましたが、これはまだ一貫しています。この結合は、呼び出し元によって行われます。

テスト対象の実際のメソッドはpostLoginであるため、postLogin内でgetShoppingCartをテストする必要さえありません。バグがあるのは適切な修正と検証が必要な唯一のバグです。挿入された依存関係を使用すると、異なる条件下で簡単にテストでき、エラーがスローされないことを確認できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.