抛出Mockito和PowerMock MethodNotFoundException

时间:2016-12-05 22:58:36

标签: java unit-testing mockito junit4 powermock

使用Powermockito和Mockito为连接池构建一些简单的单元测试时遇到以下错误,我将其包裹在Hikari CP中。测试的设置如下。令我感到困惑的是,我有一些未显示的单元测试,它们都使用相同的设置和方法。只是这一个单元测试继续失败并出现该错误。并且我在顶部的when陈述并不重要,他们都无法找到该方法。

org.powermock.reflect.exceptions.MethodNotFoundException: No methods matching the name(s) getColumnCount were found in the class hierarchy of class java.lang.Object.

at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1720)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1745)
at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:983)
at org.powermock.core.MockGateway$MockInvocation.findMethodToInvoke(MockGateway.java:317)
at org.powermock.core.MockGateway$MockInvocation.init(MockGateway.java:356)
at org.powermock.core.MockGateway$MockInvocation.<init>(MockGateway.java:307)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:142)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:125)
at com.datafiniti.utils.mysqlconnpool.MysqlConnPoolTests.executeStringQuery(MysqlConnPoolTests.java:149)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:316)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:288)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:208)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:121)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:123)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

以下是单元测试:

@RunWith(PowerMockRunner.class)
public class MysqlConnPoolTests {

private HikariConfig mockHikariConfig;
private HikariDataSource hikariDataSource;

@Before
@PrepareForTest({HikariConfig.class, HikariDataSource.class})
public void beforEachTest() throws Exception {

    // mock the hikari confic used within the connection pool
    mockHikariConfig = PowerMockito.mock(HikariConfig.class);

    // mock hikari config constructor
    PowerMockito.whenNew(HikariConfig.class)
            .withNoArguments()
            .thenReturn(mockHikariConfig);

    // mock hikari config data source setting
    PowerMockito.doNothing().when(mockHikariConfig)
            .setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");

    // mock the hikari data source used within the connection pool
    hikariDataSource = PowerMockito.mock(HikariDataSource.class);

    // mock hikari data source constructor
    PowerMockito.whenNew(HikariDataSource.class)
            .withParameterTypes(HikariConfig.class)
            .withArguments(Mockito.isA(HikariConfig.class))
            .thenReturn(hikariDataSource);
}

@Test
@PrepareForTest({MysqlConnectionPool.class, Connection.class, Statement.class, ResultSet.class, ResultSetMetaData.class})
public void executeStringQuery() throws Exception {
    PowerMockito.spy(MysqlConnectionPool.class);

    Connection mockConnection = Mockito.mock(Connection.class);
    Statement mockStatement = Mockito.mock(Statement.class);
    ResultSet mockResultSet = Mockito.mock(ResultSet.class);
    ResultSetMetaData mockMeta = Mockito.mock(ResultSetMetaData.class);

    Mockito.when(mockMeta.getColumnCount()).thenReturn(1);
    Mockito.when(mockMeta.getColumnLabel(1)).thenReturn("foo");

    Mockito.when(mockResultSet.first()).thenReturn(true);
    Mockito.when(mockResultSet.next()).thenReturn(false);
    Mockito.when(mockResultSet.getString(1)).thenReturn("bar");

    Mockito.when(mockStatement.execute(Mockito.eq("SELECT * FROM table;"))).thenReturn(true);
    Mockito.when(mockStatement.getResultSet()).thenReturn(mockResultSet);

    Mockito.when(mockConnection.createStatement()).thenReturn(mockStatement);

    Mockito.when(hikariDataSource.getConnection()).thenReturn(mockConnection);

    MysqlConnectionPool pool = new MysqlConnectionPool().create();
    List<Map<String, String>> result = pool.executeQuery("SELECT * FROM table;");

    assertEquals(1, result.size());
    assertTrue(result.get(0).containsKey("foo"));
    assertEquals("bar", result.get(0).get("foo"));
}

}

2 个答案:

答案 0 :(得分:10)

要发布回答以防万一其他人看到这个。将所有版本恢复为1.6.5解决了这个问题。

答案 1 :(得分:2)

我没有足够的声誉发表评论,所以不幸的是我正在使用答案空间发表评论。

马克尔,我遇到了类似的问题,这是我的问题 - org.powermock.reflect.exceptions.MethodNotFoundException: - when mocking java sql classes Mockito.when(mockConnection.createStatement())。thenReturn(mockStatement);为你工作?我甚至没有过去。也许你可以帮助我。我的最新结论是,因为Connection,Statement和ResultSets实际上是接口而不是类,这就是它抛出错误的原因,说它在Object的层次结构中找不到。