web-dev-qa-db-ja.com

Mockito-モックでのメソッド呼び出しのインターセプト

一般的な方法でモック上のすべてのメソッド呼び出しをインターセプトすることは可能ですか?

次のようなベンダー提供のクラスがあるとします。

public class VendorObject {

    public int someIntMethod() {
        // ...
    }

    public String someStringMethod() {
        // ...
    }

}

allメソッド呼び出しを、一致するメソッドシグネチャがある別のクラスにリダイレクトするモックを作成したいと思います。

public class RedirectedToObject {

    public int someIntMethod() {
        // Accepts re-direct
    }

}

Mockitoのwhen()。thenAnswer()コンストラクトは適切なようですが、メソッド呼び出しを引数と照合する方法を見つけることができません。とにかく、InvocationOnMockは確かにこれらすべての詳細を提供します。これを行う一般的な方法はありますか? when(vo。*)が適切なコードに置き換えられた、次のようなもの:

VendorObject vo = mock(VendorObject.class);
when(vo.anyMethod(anyArgs)).thenAnswer(
    new Answer() {
        @Override
        public Object answer(InvocationOnMock invocation) {

            // 1. Check if method exists on RedirectToObject.
            // 2a. If it does, call the method with the args and return the result.
            // 2b. If it does not, throw an exception to fail the unit test.

        }
    }
);

ベンダークラスの周囲にラッパーを追加してモックを簡単にすることは、次の理由からオプションではありません。

  1. 既存のコードベースが大きすぎます。
  2. 非常にパフォーマンスが重要なアプリケーションの一部。
26
Karle

私が望むのは:

VendorObject vo = mock(VendorObject.class, new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) {

        // 1. Check if method exists on RedirectToObject.
        // 2a. If it does, call the method with the args and return the
        // result.
        // 2b. If it does not, throw an exception to fail the unit test.

    }
});

もちろん、このアプローチを頻繁に使用する場合は、回答を匿名にする必要はありません。

documentation から:「これは非常に高度な機能であり、通常、適切なテストを作成するためにこの機能を必要としません。ただし、レガシーシステムで作業する場合には役立ちます。」あなたのように聞こえます。

39
jhericks