PowerMock, пытающийся имитировать статический getConnection, дает недопустимое состояниеException: не удалось преобразовать класс

Я пытаюсь сделать статический метод getConnection() из класса JDBCConnectionFactory. Я использую powerMock + mockito для насмешек вместе с Junit4.

Испробованные решения:

  1. Погуглил и изменил множество версий javassist.jar. Ни один из них не работал.
  2. Приведенный ниже код работает. Но когда я заменяю Another.class на JDBCConnectionFactory, он начинает выдавать указанное ниже исключение.
  3. Когда я удаляю аннотацию PrepareFortest и пытаюсь запустить этот JUNIT, он начинает выполнять сам метод getConnection (который я хочу высмеять).

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(AnotherClass.class)
    public class MockitoTester {
    
       @Test
       public void myTest() throws Exception {
    
          mockStatic(AnotherClass.class);
          Mockito.when(AnotherClass.getStaticString()).thenReturn("mock static string ");
          System.out.println(AnotherClass.getStaticString());
    
       }
    
    }
    

Я получаю следующее исключение:

java.lang.IllegalStateException: Failed to transform class with name org.onesync.dq.gui.testng.testNG.MockitoTester. Reason: 3
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:207)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:145)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:133)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:39)
    at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:217)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:59)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
    at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:31)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:31)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:24)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:33)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 3
    at javassist.bytecode.ByteArray.write16bit(ByteArray.java:40)
    at javassist.bytecode.StackMapTable$Shifter.update(StackMapTable.java:744)
    at javassist.bytecode.StackMapTable$Shifter.sameFrame(StackMapTable.java:720)
    at javassist.bytecode.StackMapTable$Walker.stackMapFrames(StackMapTable.java:194)
    at javassist.bytecode.StackMapTable$Walker.parse(StackMapTable.java:179)
    at javassist.bytecode.StackMapTable$Shifter.doit(StackMapTable.java:714)
    at javassist.bytecode.StackMapTable.shiftPc(StackMapTable.java:693)
    at javassist.bytecode.CodeIterator.insertGap0(CodeIterator.java:676)
    at javassist.bytecode.CodeIterator.insertGap(CodeIterator.java:636)
    at javassist.bytecode.CodeIterator.insertGapCore(CodeIterator.java:467)
    at javassist.bytecode.CodeIterator.insertGap(CodeIterator.java:413)
    at javassist.expr.Expr.replace0(Expr.java:298)
    at javassist.expr.FieldAccess.replace(FieldAccess.java:213)
    at org.powermock.core.transformers.impl.MainMockTransformer$PowerMockExpressionEditor.edit(MainMockTransformer.java:276)
    at javassist.expr.ExprEditor.loopBody(ExprEditor.java:197)
    at javassist.expr.ExprEditor.doit(ExprEditor.java:90)
    at javassist.CtClassType.instrument(CtClassType.java:1289)
    at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:75)
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:203)
    ... 29 more

Надеюсь, что приведенная выше информация поможет. Любые идеи/подходы/предложения приветствуются. Спасибо


person Simranjeet Singh Chawla    schedule 07.02.2013    source источник
comment
Какие именно версии junit, mockito, powermock и javassist вы используете? Решение номер 3 определенно НЕ является ответом, вам нужна аннотация @PrepareForTest.   -  person Tom Tresansky    schedule 07.02.2013
comment
Какой JDK вы используете?   -  person bowmore    schedule 07.02.2013
comment
Junit 4, mockito-all — 1.9.5, powermock — 1.5, javassist — пробовал версии с 3.10 по 3.17, JAVA 1.6   -  person Simranjeet Singh Chawla    schedule 07.02.2013
comment
Этот тест сработал для меня почти сразу. Не могли бы вы опубликовать свой «AnotherClass» или что-то более конкретное, чтобы я мог лучше понять, в чем может быть проблема?   -  person John Ericksen    schedule 11.02.2013
comment
Я не уверен, но обычно я выделяю PowerMockito для статического импорта. Извините, не вижу этого в вашем импорте, а также в коде   -  person Eugen Martynov    schedule 13.02.2013


Ответы (2)


Иногда вам нужно использовать синтаксис doReturn(). Вы пробовали следующее с JDBCConnectionFactory? Я буду использовать ваш пример AnotherClass:

@RunWith(PowerMockRunner.class)
@PrepareForTest(AnotherClass.class)
public class MockitoTester {

  @Test
  public void myTest() throws Exception {
    mockStatic(AnotherClass.class);
    PowerMockito.doReturn("mock static string ").when(AnotherClass.class, "getStaticString");
    System.out.println(AnotherClass.getStaticString());
  }
}

См. также PowerMockitoStubber по адресу https://www.javadoc.io/doc/org.powermock/powermock-api-mockito/1.5

person Matt Lachman    schedule 11.02.2013
comment
Большое спасибо, это действительно помогает мне! Я не знаю, почему Powermock дает два одинаковых метода, так что смущайтесь :( - person kidnan1991; 06.03.2018

посмотрите ArrayIndexOutOfBoundsException при запуске теста PowerMock, я решил таким образом, обновите версию javassist.jar

person fatmind    schedule 27.03.2013