嘲弄一堂课的问题

Lio*_*orH 5 java mockito jdbi

我试图用mockito 模拟JDBI 的Query类,但它无法模拟其基类的方法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
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用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 ....
Run Code Online (Sandbox Code Playgroud)

任何想法如何解决这个问题?

Bri*_*ice 4

bind中的方法SqlStatement是最终的(例如SQLStatement#bind(String, int)),因此您不能使用 Mockito 来模拟它们,这是 JVM 的限制(编辑:),mockito目前无法绕过。

\n\n


\nEDIT2:请注意,正如下面的评论指出的那样,对上面所写的内容存在一些误解,这需要我的澄清:

\n\n

    \n
  • JVM 的限制意味着您无法加载带有最终访问标记的类型的子类,也无法覆盖带有最终访问标记的方法,否则您将收到VerifyError。\xc2\xa78.1.1.2 Java 语言规范的最终类 \xc2\xa78.4.3.3 JLS 的最终方法 \xc2\xa74.10 Java 虚拟机规范
  • \n
  • mockito 无法绕过意味着 Mockito 目前无法克服最终类或最终方法来模拟它们,因为目前 Mockito 使用 CGLIB 来生成要模拟的类型的子类。但其他框架(如 PowerMock 或 JMockit)也许能够做到这一点,因为它们有其他策略来克服这个问题。
  • \n
\n\n
\n\n

您的选择是更改您的设计,这样您就不必存根这些交互,或者您必须使用 PowerMock,它使用类加载器的复杂技巧来重写类字节码(不是我首选的方法,尽管 PowerMock 在技术上令人印象深刻)。

\n\n

希望有帮助。

\n