オーバーロードされた関数を単体テストするにはどうすればよいですか?
-
07-07-2019 - |
質問
つまり、次のようなクラスがあります:
public class MyClass
{
DatabaseDependency _depend;
public MyClass(DatabaseDependency depend)
{
_depend = depend;
}
public string DoSomething(DBParameter database)
{
var result = _depend.GetResults(database, ...);
string response = String.Empty;
// some logic to process the result
return response;
}
}
DBParameterは、Server、DBName、DBTypeなどのプロパティを含む単純な値クラスです
ここで、DBParameterパラメーターの代わりに接続文字列を受け入れるように、DoSomethingにオーバーロードを追加します(DatabaseDependencyには既に接続文字列を受け入れるGetResultsオーバーロードがあると仮定します)。
私の質問:DatabaseDependency.GetResultsからの結果を処理するために使用されるさまざまな論理パスを記述するユニットテストがいくつかあります。オーバーロードをDoSomethingに追加するときは、本質的にコードをリファクタリングして、このロジックが両方のオーバーロードで再利用されるようにします(つまり、おそらくプライベートメソッドに移動します)。これを単体テストする正しい方法は何ですか?追加する新しいオーバーロードのすべての論理パスを検証するには、同じ数の単体テストが必要ですか?
解決
文字列を取るオーバーロードメソッドが接続オブジェクトに変換してから元のオブジェクトに委任することに自信がある場合は、テストメソッドをもう1つ追加する必要があります。
ただし、デリゲートが発生しないように、基になるオーバーロードされたメソッドをリファクタリングすると、これは壊れます。このシナリオでは、両方の方法のすべてのテストをより自信を持って複製できると思います。
最初のルートが最も実用的だと思います。ただし、コードカバレッジ分析を時々実行することをお勧めします。これは、後でさらにテストが必要かどうかを示します。
他のヒント
コードが現在の見た目のままである場合、はい:そのメソッドもユニットテストする必要があります。テスト作業を本質的に複製します。
ただし、1つのメソッドが他のメソッドを単純に呼び出すように機能を実装することが理にかなっている場合は、他のメソッドを仮想にすることができます。これにより、テスト固有のサブクラスを作成して、仮想メソッドが他のメソッドによって正しい値で呼び出されていることを確認するだけで済みます。
1つ以上の単体テストで検証されたら、そのメソッドをもうテストする必要はありません。メソッドが他のメソッドを正しく呼び出すことを証明し、その方法にテスト作業を集中します。
はい、一般的な処理をプライベートメソッドにリファクタリングします。テストの考慮事項に関係なく、とにかくこれを行うと仮定します。コードの複製は悪いです。テストについて考えることで、私たちは正しいことをするようになります。
次に、オーバーロードされた開始パスごとにいくつかの簡単なテストがあります。
ブラックボックスまたはホワイトボックスのテストを行っているかどうか、またアプリケーションがメソッドの両方のバージョンを使用しているかどうかによって異なります。
実装をテストするだけであると想定している場合は、単に「メイン」バージョンをテストするだけで構いません。提示されたAPI(javadocsなど)のみを知っているテストライターの方針に沿って考えている場合は、APIのみに基づいてテストする必要があります。これは、両方のメソッドを完全にテストすることを意味します。
アプリケーションが1つのメソッドのみを使用している場合、もう一方を非推奨にし、非推奨メソッドが所定のバージョンにまだ存在する場合に失敗するバージョン条件テストを作成します。 IE:ある時点で非推奨のメソッドが削除されるようにします。