2016-12-05 5 views
1

Выполняя приведенную ниже ошибку при использовании Powermockito и Mockito для создания простых модульных тестов для пула соединений, я сделал это, обертывая Hikari CP. Настройка тестов приведена ниже. Что меня сбивает с толку, у меня есть целый ряд модульных тестов, которые не показаны, и все они проходят с использованием одной и той же настройки и методов. Только эта единичная проверка продолжает терпеть неудачу с этой ошибкой. И не имеет значения, что заявление when, которое я поставил наверху, все они не могут найти метод.Mockito и PowerMock MethodNotFoundException выбрасывается

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")); 
} 

}

+0

Попробуйте поставить @PrepareForTest со всем классом перед «публичным классом MysqlConnPoolTests» и удалите его перед тестированием. Иногда я вижу странное поведение, когда PrepareForTest объявляется на тестовом уровне. –

ответ

6

Отправляя ответ, на случай, если кто-то еще это увидит. Возврат всех версий к 1.6.5 решил проблему.

+0

Да, переход от 1.6.6 до 1.6.5 работал для меня. – Fergal

+0

Это работает спасибо! Имела та же проблема. –

+0

Перемещение на v1.7.0 также решило проблему –

2

У меня нет достаточной репутации комментировать, поэтому, к сожалению, я использую ответ пространства для комментариев.

Markll, я бегу на аналогичные вопросы, вот мой вопрос SO - org.powermock.reflect.exceptions.MethodNotFoundException: - when mocking java sql classes ли Mockito.when (mockConnection.createStatement()) thenReturn (mockStatement). работа для вас? Моя даже не прошла мимо этого. Может быть, вы можете мне помочь. Мой последний вывод заключается в том, что Connection, Statement и ResultSets фактически являются интерфейсами, а не классами, поэтому он бросает ошибку, заявив, что не может найти ее в иерархии Object.

+1

Спасибо за указание, определенно похоже на ошибку. Я выполнил некоторую отладку через мой и понял, что он меняет класс, в котором он ищет метод, от метода, заданного java.lang.Object. Конечно, метод, о котором я прошу, не существует. – MarkII

+0

Да, это звучит как ошибка. Я бы предположил, что вы должны написать его в разделе вопросов PowerMock github repo с тем, что вы наблюдали при отладке. Я еще не спустил отверстие для отладки кролика, или я бы сделал это сам. – user2237511

+1

Кажется, что уже зарегистрирована ошибка - https://github.com/powermock/powermock/issues/717. – user2237511

Смежные вопросы