web-dev-qa-db-ja.com

Mockito:メソッドA.aが呼び出されたら、B.bを実行します

JUnitテストにMockitoを使用しています。したがって、テストしたいコードから使用される特定のクラスAがあります。

_class A{

    public A(){}

    public final String a(String x){
        return "A.a: " + x;
    }

}
_

そして、メソッド呼び出しA.aを、同じ引数と同じタイプの戻り値を持つ別のメソッド呼び出しに置き換えたいと思います。ご覧のとおり、最終的なクラスを拡張してメソッドaをオーバーライドすることはできません。だから私が今持っているのはメソッドB.bを持つ別のクラスBです:

_class B{

    public B(){}

    public String b(String x){
        return "B.b: " + x;
    }

}
_

ここで、コードからA.aが呼び出されるたびに、代わりにB.bの戻り値が使用されることを確認したいと思います。 Xの値を知らなくても、Mockito(Mockito.when(A.a(x)).thenReturn(B.b(x));のようなもの)で同じパラメーターxを使用してこれを達成する可能性はありますか?

助けていただければ幸いです、よろしくお願いします!

16
user1448982

Mockitoの制限 によると、Mockitoで生成されたモックのfinalメソッドをオーバーライドすることはできません。ただし、 Powermock を使用して実行時にコードをハッキングし、Mockitoがその仕事を行えるようにすることができます。

3
Sergej Zagursky

Mockitoモックは、クラスを拡張し、メソッドをオーバーライドすることで機能します。これは、A.a(String)では不可能です。これを実現したい場合は、最後の修飾子を削除する必要があります。

A.a(String)が最終的ではないと仮定すると、あなたが求めることはmockitoで完全に実行可能です。

given(mockA.a(anyString()).willAnswer(returnOfB(bInstance));

Answer<String> returnOfB(final B bInstance) {
    return new Answer<String>() {
         public String answer(Invocation invocation) {
             String arg = (String) invocation.getActualArguments()[0];
             return bInstance.b(arg);
         }
    };
}

この回答は電話で書かれており、タイプミスや間違った名前が付いている可能性があることに注意してください。ただし、目的を達成するために何をすべきかを理解する必要があります。

乾杯

20
Brice

基本的に私はあなたのセットアップを取り、それを使ってユニットテストを書きました。最初にポップアップしたのは、次のことを明示的に示すエラーメッセージでした。

org.mockito.exceptions.misusing.MissingMethodInvocationException:when()には、「モックのメソッド呼び出し」でなければならない引数が必要です。

そして、トレースの後半で、「final/private/equals()/ hashCode()メソッドのいずれかをスタブします。これらのメソッドcannotスタブ/検証する」と述べています。

したがって、Mockitoによると、finalメソッドをスタブ化することはできません。それだけです。

編集:したがって、最後の修飾子を削除するか、このクラスをそのまま使用する場合は、別の方法を見つける必要があります。

1
Simon Hellinger