1

実行時に Mockito によって作成されたモックをラップし、ラッパーでメソッドを呼び出すと、ラップされたモックは呼び出されません。下記を参照してください:

これは私が実行するテストです:

import static org.mockito.Mockito.verify;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;
import org.junit.Test;
import org.mockito.Mockito;

public class MyTest {

    @Test
    public void mockIsCalled() {
        final Bar bar = Mockito.mock(Bar.class);
        final Bar wrapper = wrap(bar);
        wrapper.foo();
        verify(bar).foo();
    }

    @SuppressWarnings("unchecked")
    private <T> T wrap(final T objToWrap) {
        return (T) Enhancer.create(objToWrap.getClass(), NoOp.INSTANCE);
    }

}

ここで、バーは次のとおりです。

public interface Bar {
    String foo();
}

テストは失敗し、得られる出力は次のとおりです。

java.lang.NoSuchMethodError: java.lang.Object.foo()Ljava/lang/String;
    at Bar$$EnhancerByMockitoWithCGLIB$$d2b59df8.foo(<generated>)
    at MyTest.mockIsCalled(MyTest.java:18)
...

Bar を次のようにクラスにすると:

public class Bar {

    public String foo() {
        System.out.println("foo");
        return null;
    }

}

テストは引き続き失敗fooし、コンソールに出力され、出力が得られます。

Wanted but not invoked:
bar.foo();
-> at MyTest.mockIsCalled(MyTest.java:20)
Actually, there were zero interactions with this mock.

    at MyTest.mockIsCalled(MyTest.java:20)
...

私は混乱しています。

私が解決しようとしている実際の問題は、ラップされた動的プロキシのメソッド呼び出しをメモ化するために、(コンポーネント バインディングを介して Mule によって注入された) 動的プロキシをラップすることです。インターフェイスを拡張しなくても動的プロキシ オブジェクトをラップできるように、十分に汎用的なものにしたいと考えています。

ありがとう

4

1 に答える 1

1

Bar クラスの場合に見られる問題は、cglib の奇抜さがなければ、インターフェイス バージョンでも見られるでしょう。モックをラップしているのではなく、新しいオブジェクトを作成しています。したがって、元のモックは実行されません。

クラス バージョンを使用するために、インターフェイスを params として受け入れるバージョンを試しましたcreate()か?

あなたの使用シナリオを完全に理解しているかどうかはわかりませんが、Mockito 固有の何かについてはspy()、新しいオブジェクトをモックする代わりに、cglib によって作成されたプロキシを使用してみてください。

率直に言って、cglib についてはあまり知りませんがCallback、元のオブジェクトを含み、委任する独自の を実装できるかもしれません。の代わりにそれCallbackを提供できます。Enhancer.create()NoOp

于 2012-12-08T20:43:30.410 に答える