2

外部 jar を使用するクラスを考えてみましょう。このクラスは、オブジェクト、、およびDを介して取得されるタイプ のオブジェクトを処理します。これらはすべて、jar からの外部オブジェクトです。ABC

class DProcessor() {  
    public void process(PoolOfA pool) {
        A a = pool.borrowObject()
        ...
        B b = a.getB()
        C c = b.getC()
        for (D d : c.getAllDs()) {
            // Do something meaningful with d
        }
    }
}

単体テストの方法を教えてくださいprocess(PoolOfA pool)

これまでの私の最善の策は、すべての外部クラスのモックを作成することです。

PoolOfA pool = mock(PoolOfA.class);

A a          = mock(A.class);
B b          = mock(B.class);
C c          = mock(C.class);

D d1         = mock(D.class);
D d2         = mock(D.class);
D d3         = mock(D.class);
D d4         = mock(D.class);

List listOfDs = new ArrayList<D>();
listOfDs.add(d1);
listOfDs.add(d2);
listOfDs.add(d3);
listOfDs.add(d4);

// Set specific behaviour for each d

when(pool.borrowObject()).thenReturn(a);
when(b.getC()).thenReturn(a);
when(c.getAllDs()).thenReturn(d);
when(b.getC()).thenReturn(c);
when(c.getAllDs()).thenReturn(listOfDs);

これは面倒でエレガントではないようです。より良い方法はありますか?

4

3 に答える 3

4

もちろん、より良い方法はメソッドを書き直すことです。しかし、何らかの理由でそれができない場合、mockito は「ディープ スタブ」と呼ばれる優れた機能を提供します。ドキュメントをチェックしてください。

于 2012-12-16T10:13:44.463 に答える
2

プロセスが実際に行うことは、ループ内でいくつかの D を処理することです。最初に、署名を変更して明確にします。

public void process(Collection<D> allDs)

これで、D のみをモックすることで、より簡単にテストできます。

そのメソッドは、既存のメソッドを置き換えることができる場合はパブリックにするか、たとえば公開したくない場合はパッケージをプライベートにすることができます。後者の場合でも、もう一方のprocessメソッド (poolOfA を受け取るメソッド) が適切に D を抽出することをテストしたい場合があります。しかし、それは、正しくないように見えるprocess(PoolOfA)について多くのことを知る必要があることを意味します。poolOfA

これは、この「テスト可能なコードを書くためのガイド」によって促進されたアイデアの 1 つであり、興味深い概念が含まれていると思います。あなたが言及したことは、おそらく「コラボレーターを掘り下げる」セクションに分類されるでしょう。

于 2012-12-16T10:06:08.497 に答える
1

process メソッドを少し再設計することをお勧めします。現在、2 つのことを担当しています。入力の内部から D の Iterable を抽出して処理することです。

したがって、実際には、PoolOfA 型の入力を期待していると宣言しているメソッドは、このオブジェクトにはまったく関心がありません。中身を欲しがる。メソッドが Iterable を取るものとして宣言し、正しい入力を与える責任を呼び出し元に渡します。これにより、メソッドの意図が明確になり、テストが容易になります。

「これは本当の解決策ではありません。問題を別の場所に移動しているだけです。呼び出し方法をテストする必要があります。」

はい、いいえ。最初に、すべてを UT にする必要はないことを覚えておいてください。UT の作業は、コードのアルゴリズム部分に集中する必要があります。些細なオブジェクトの相互作用をスキップしてもかまいません。

主張する場合は、クラスの過去のみをモックするために PowerMock などのより強力なモック ライブラリを使用できますが、これは別の質問の議論です。

于 2012-12-16T10:09:31.077 に答える