我们正在使用PowerMock为Jersey Java REST服务编写单元测试。我们必须使用PowerMock,因为我们在遗留系统中使用了许多静态方法。我们在EasyMock上使用PowerMock。每当我们尝试从JerseyTest继承时,整个框架都会失败。
这是一个基于gradle的项目,下面是相关的build.gradle
行。
testCompile 'junit:junit:4.12'
testCompile group: 'org.easymock', name: 'easymock', version: '3.5.1'
testCompile group: 'org.easymock', name: 'easymockclassextension', version: '3.2'
testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '1.7.3'
testCompile group: 'org.powermock', name: 'powermock-api-easymock', version: '1.7.3'
我们已经启动并运行了一些EasyMock单元测试,因此我们知道我们的导入工作正常。问题是,由于我们正在测试Jersey Web服务,因此我们的单元测试继承自JerseyTest。在没有继承JerseyTest的情况下编写PowerMock单元测试工作正常。但是当我们尝试从JerseyTest继承时,它们都崩溃了。谷歌让我们失望(显然,没有其他人编写泽西岛网络服务的人尝试使用过PowerMock)。
我们所做的事情非常直截了当。这有效:
@RunWith(PowerMockRunner.class)
public class PowerMockTest {
private final static String TARGET = "ourwebservice/";
@Test
public void testConfigurationGet() {
// do stuff, but no Jersey web service calls
}
}
将类声明更改为从JerseyTest继承:
public class PowerMockTest extends JerseyTest {
我们彻底失败了。我们使用Eclipse作为IDE,这是JUnit窗口中显示的错误:
initializationError (0.000 s)
“故障跟踪”窗口提供了更多详细信息:
java.lang.VerifyError: Inconsistent stackmap frames at branch target 38
Exception Details:
Location:
com/ourcompany/ourproduct/rest/PowerMockTest.<init>()V @38: aload_1
Reason:
Type uninitializedThis (current frame, locals[1]) is not assignable to 'com/ourcompany/ourproduct/rest/PowerMockTest' (stack map, locals[1])
Current Frame:
bci: @24
flags: { flagThisUninit }
locals: { uninitializedThis, uninitializedThis, top, 'java/lang/Object' }
stack: { 'java/lang/Object', 'java/lang/Object' }
Stackmap Frame:
bci: @38
flags: { flagThisUninit }
locals: { uninitializedThis, 'com/ourcompany/ourproduct/rest/PowerMockTest' }
stack: { }
Bytecode:
0x0000000: 2a4c 1211 b800 1703 bd00 1912 1ab8 001e
0x0000010: b800 244e 2db2 0028 a500 0e2a 01c0 002a
0x0000020: b700 2ea7 0009 2bb7 0030 0157 a700 0301
0x0000030: 3a05 2ab8 0036 b1
Stackmap Table:
append_frame(@38,Object[#14])
chop_frame(@44,1)
same_frame(@47)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetPublicMethods(Class.java:2902)
at java.lang.Class.getMethods(Class.java:1615)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.getTestMethods(PowerMockJUnit44RunnerDelegateImpl.java:109)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.<init>(PowerMockJUnit44RunnerDelegateImpl.java:85)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl.<init>(PowerMockJUnit47RunnerDelegateImpl.java:42)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit49RunnerDelegateImpl.<init>(PowerMockJUnit49RunnerDelegateImpl.java:25)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:172)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:48)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:108)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:71)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:36)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:87)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:73)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:46)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:522)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
我们甚至无法进入调试方法;它之前就失败了(注意,测试实际上还没有做任何事情;我们只是试图先把事情设置好。)
任何人都知道发生了什么?我们有某种配置错误吗?我们必须切换到Mockito吗?