5

サードパーティの抽象クラスを拡張する新しいクラスを作成しました。新しいクラスは、抽象クラスのメソッドを呼び出します。私が抱えている問題は、単体テストを作成しようとするときです。サードパーティのクラスが必要とする正確な詳細がわからないため、テストの作成方法がわかりません。

以下の AbstractDecoratorMapper は、SiteMesh が正しく機能するために拡張する必要がある SiteMesh 固有のクラスです。ドキュメントからわかる限り、コンポジションは使用できません。

public final class PartnerDecoratorMapper extends AbstractDecoratorMapper {

    @Override
    public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
        super.init(config, properties, parent);
    }

    @Override
    public Decorator getDecorator(HttpServletRequest request, Page page) {
        if (super.getDecorator(request, page).getName().equalsIgnoreCase("default")) {
            return getNamedDecorator(request, "externalPartnerDefault");
        }
        return super.getDecorator(request, page);
    }
}

このツールが役立つことがあれば、私は JMock を使用します。

4

4 に答える 4

4

サードパーティのライブラリの詳細を知る必要はありません...それらをモックして、期待するものを返すだけです。

継承している場合は、本番環境で使用されるようにクラスを設定し、通常の使用で呼び出す必要があるメソッドを呼び出すことができます。確認する必要があるのは、結果が期待どおりかどうかだけです。(サードパーティのクラスがテストでどのように機能するかを正確に知る必要はありません)。

実装したすべてのコードが実行されたかどうかを確認するには、eclemma のようなプラグインを使用してカバレッジを確認できます - http://www.eclemma.org/ )

于 2012-06-11T10:00:31.780 に答える
3

JMockを使用すると、私の知る限り、テスト対象のクラスのスーパークラスへのモック呼び出しを行うことはできません。

この関連する質問への回答は役立つかもしれませんが、主な回答は、これをサポートするモックフレームワーク(JMockitをお勧めします)に切り替えることです。

于 2012-06-11T11:20:01.477 に答える
2

あなたが尋ねるかもしれない2つのことがあります。両方答えてみます。

考えられる質問 1) 追加機能をテストするにはどうすればよいですか?

考えられる質問 2) 組み合わせた機能が適切かどうかをテストするにはどうすればよいですか?

質問 1 から始めましょう。

シンプルなピーリングをお勧めします。ここにテクニックのビデオがあります: http://www.youtube.com/watch?v=p0tILwRZH5Q (ビデオは c# ですが、Java でも基本的に同じです)

これは、後で次のコードが得られることを意味します

@Override
public Decorator getDecorator(HttpServletRequest request, Page page) {
    Decorator d = super.getDecorator(request, page);
    return getResolvedDecorator(d, d.getName(), request);

}
public Decorator getResolvedDecorator(Decorator current, String name, HttpServletRequest request) {
    if (name.equalsIgnoreCase("default")) {
        return getNamedDecorator(request, "externalPartnerDefault");
    }
    return current;
}

これで、次のような呼び出しでこれをテストできます

assertEquals(expected, new PartnerDecoratorMapper().getResolvedDecorator(null, "default", MockHttpServletRequest);

テストと意図をより明確にするために、HttpServletRequest からもデータを削除することをお勧めします。

注: これにより、結果がキャッシュされるため、super.getDecorator() への呼び出しが 1 回だけ発生するというパフォーマンス上の利点が追加されます。

追記: init() のオーバーライドは不要であり、実際には何もしないことにも注意してください。

質問 2: 望ましい動作が何であるかを述べていないため、これは難しい質問です。これは工場のパターンであると想定しているので、おそらく次のような方法で機能します

| | http 要求品質 1 | ページ品質 1| 予想されるデコレーター | | | /mypath/マイページ | ステータス = フー | マイデコレータ |

(上記のグラフに何を含めるべきか、どのように見えるべきかはわかりません) この動作が得られたら、それを確認するためのテストはかなり簡単になります。

ハッピーテスト、ルウェリン

于 2012-06-11T11:58:58.773 に答える
1

サードパーティのクラスが必要とする正確な詳細がわからないため

どんな種類のテストでも、何かが実際に何をするかを、それがすべきことと比較します。何かが何をすべきかを理解するまでテストすることはできません:「第3部のクラスが必要とするもの」。

また、基本クラスに何が必要かわからない場合、どのようにして派生クラスを作成するための合理的な試みを行うことができますか?拡張しているクラスのAPIドキュメントは何と言っていますか?

問題はおそらくそのようなAPIドキュメントがないことですか、それとも有益ではありませんか?クラスはそうfinalではありませんが、実際には基本クラスとして使用することを意図していない可能性があります。これらのいずれも、APIの設計が不十分であることを示しており、わざわざ使用しないでください。

それとも、正確な詳細がわからないという重大な難しさですか?これは、アプローチの欠陥である可能性があります。通常、正確な詳細について推測することはできず、またそうしてはなりません。コードは文書化されたAPIに準拠している必要があり、文書化されたAPIに記載されていないものを想定しないでください。これは、テンプレートメソッドがいつ呼び出されるか、またはそれらにどの値が渡されるかを知ることができないことを意味する場合があります。interface基本クラスが、または非クラスを実装するように宣言されたオブジェクトを渡すことによってテンプレートメソッドと通信する場合final(つまり、それらのタイプは指定されますが、クラスは指定されません)、それらのオブジェクトがどのクラスを持つかを知ることはできません。

于 2012-06-11T12:24:13.787 に答える