2

最近、たくさんの単体テストを書いています。きれいな解決策が見つからないシナリオがあります...

あなたがメソッドの獣を持っているとしましょう:

public void bigMethod() {
    // a lot of code goes in here
}

あなたの生活を楽にし、コードをよりクリーンにするために、あなたは通常、そのような獣をより小さな内部メソッドに分解します:

public void bigMethod() {
    a();
    b();
    c();
    // etc.
}

すべての内部メソッド(a()、b()、c()など)を個別にテストできます。問題はbigMethod()であり、これもテストする必要がありますが、実行しているのは他のメソッドの呼び出しを連鎖させることだけであり、それらはすでに徹底的にテストされています。

そのようなシナリオにどのようにアプローチしますか?a()、b()、およびc()が適切な順序で呼び出されていることを確認する必要があるため、bigMethod()をテストしないままにすることはできません。ただし、bigMethod()のテストを作成すると、テストで多くの重複が発生します。そして、あなたがそれを頻繁に行うので、毎回そこでこの重複を減らすことは多くの面倒です。

私の頭に浮かぶアイデアの1つは次のとおりです。

public void bigMethod() {
    helperA.a();
    helperB.b();
    helperC.c();
    // etc.
}

このシナリオでは、すべてのヘルパークラスをテストしてから、bigMethod()がそれらをinOrderで呼び出すことを確認します。素晴らしくてきれいですが、プロジェクトに非常に小さなクラスがたくさん導入されています。

忍者のテストを手伝ってください!

4

4 に答える 4

2

通常、ベスト プラクティスは、ユニット テストで をテストするbigMethod()ことです。これは公開されているメソッドであり、テストでは内部のプライベート ヘルパー メソッドを無視する必要があります。

bigMethod()あなたが指摘したように、クラスの内部動作についてあまりにも多くのことを知っているテストは脆弱になる傾向があり、 の内部実装をリファクタリングする場合は大幅に変更する必要があります。

したがって、私のアドバイスは、テストを書き直して、bigMethod()コードの重複を心配する必要がないようにすることです。

于 2012-10-15T17:20:41.977 に答える
1

良い解決策が見つからないのは、メソッドを連続した断片に分割しても、実際には改善されなかったからです。実際、おそらくインスタンス変数を使用して、メソッドの境界を越えて状態を共有する必要があったため、デバッグが困難になった可能性があります。

これはあなたが聞きたかった答えではないことはわかっていますが、本当にコードを改善したい場合は、一歩下がって何bigMethodが機能するかを再分析して書き直して、さまざまな機能を適切なインターフェイスを持つクラスに分離します。が呼び出される場所もリファクタリングするのが理想的ですがbigMethod、それは割り当てられたタスクの範囲外である可能性があることを認識しています。

于 2012-10-15T17:26:22.427 に答える
1

まず、以下のすべてのテキストはa()b()c()がパブリック メソッドである場合に意味があります。

bigMethod()内部呼び出しの結果に焦点を当ててテストa()b()ますc()

これらの各メソッドを個別にテストするのとはまったく別のシナリオです。

したがって、私によると、特定のテストを追加しても、bigMethod()いくつかの重複は明らかになりませんが、代わりにチェックする新しい興味深いケース、つまり内部呼び出しのコラボレーションが明らかになります。

コードの最初のバージョンを保持してテストします:)

実際、これはプロジェクトの配信に関する同様の一般的な問題のようです。

3 つのプロジェクトが別々に開発され、最終的にそれらがまとめられたとします。

次の 3 つの可能性があります。

  • 3 つのプロジェクトのみを個別にテストする
  • 3 つのプロジェクトの混合のみをテストするのを待ちます
  • これらの両方の方法をテストしてください!

論理的には、3 番目の可能性が望まれます。単体テストも同様です。

a()またはb()、予期しない結果が得られることをc()妨げない予期しない動作が発生する可能性がありbigMethod()、逆にbigMethod()、独立したメソッドのテストが成功したにもかかわらず、予期しない結果が発生する可能性があります。

于 2012-10-15T17:29:01.643 に答える
0

解がはっきりと見えないのはa()b()との性質をよく考えて定義していないからだと思いますc()a()次の、 、のうちどれが であるかを確実に把握する必要がありb()ますc()

  1. その内部の不可分なサブパーツは、bigMethod()その外部では意味がありません。

  2. クラスのパブリック コントラクトの一部であるメソッドは、その結束に貢献し、外部から独立して呼び出すことができます。

  3. 結局のところ、実際にはクラスに属さないメソッド。それらを取り除くことは、クラスの結束に役立ち、より簡単に再利用できるようになります。

それが分かれば、それらをテストする方法の答えは簡単です。

  1. アトミック ブロックとしてテストするだけbigMethod()です。内部サブパーツの可視性スコープをいじってテスト可能にしようとしないでください。

  2. テストしa()、独立して。次に をテストするには、部分モックを使用して、サブメソッドが正しい順序で呼び出されることを確認します。の結果をテストすることもできます。これにより、ユニットテストよりも統合テストのようなものになり、言及した重複の問題があります。b()c()bigMethod()bigMethod()

  3. テストしa()、独立して。次に をテストするには、それらのオブジェクトにモックを使用し、 がこれらのオブジェクトと正しく通信することを確認します。b()c()bigMethod()bigMethod()

于 2012-10-16T09:04:18.983 に答える