5

JDBIのQueryクラスをmockitoでモックしようとしていますが、基本クラスのメソッドをモックできませんSqlStatement

以下のコードを実行すると、whenステートメントは実際に基本クラスの具象実装を呼び出しており、で失敗しNullPointerExceptionます。

import java.util.Map;

import org.junit.Test;
import org.skife.jdbi.v2.Query;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class TestClass {
    @Test
    public void testBind() {
        Query<Map<String,Object>> mockQuery = mock(Query.class);
        when(mockQuery.bind("xxx", 5)).thenReturn(mockQuery); //this line fails
        //more stuff here
    }
}

EasyMockでもこれを試しましたが、同じ結果が得られましたが、このメソッドをモックできません。

より詳しい情報:

  • Mockitoのバージョンは1.9.5です
  • JDBIのバージョンは2.4.1(現在dropwizardに同梱されているもの)です。

例外は次のとおりです。

    java.lang.NullPointerException
        at org.skife.jdbi.v2.SQLStatement.bind(SQLStatement.java:434)
        at TestClass.testBind(TestClass.java:17)
            at ....

これを回避する方法はありますか?

4

2 に答える 2

4

bindのメソッドSqlStatementは final (たとえば) であるため、Mockitoを使用してそれらをモックすることはできません。これは、mockito が現時点でバイパスできないSQLStatement#bind(String, int)JVM (EDIT:) の制限です。


EDIT2:以下のコメントが指摘しているように、上記の内容には誤解があることに注意してください。これには、私の側で明確にする必要があります。

  • JVM の制限により、最終アクセスのフラグが立てられた型のサブクラスをロードできず、最終アクセスのフラグが立てられたメソッドをオーバーライドできません。そうしないと、VerifyError が発生します。§8.1.1.2 Java 言語仕様の最終クラス §8.4.3.3 JLS の最終メソッド §Java 仮想マシン仕様の 4.10
  • Mockito がバイパスできないということは、現在 Mockito が CGLIB を使用してモックするタイプのサブクラスを生成するため、Mockito がそれらをモックするために最終クラスまたは最終メソッドを克服できないことを意味します。ただし、他のフレームワーク (PowerMock や JMockit など) は、これを克服するための他の戦略を持っているため、それを実行できる場合があります。

オプションは、設計を変更してそれらの相互作用をスタブする必要がないようにすることです。または、クラスローダーで複雑なトリックを使用してクラスバイトコードを書き換える PowerMock を使用する必要があります (PowerMock は技術的に印象的ですが、私の好みのアプローチではありません)。

それが役立つことを願っています。

于 2013-01-09T19:29:28.883 に答える
0

試す

Mockito.doReturn(mockQuery).when(mockQuery).bind("xxx",5);
于 2013-01-09T17:36:58.003 に答える