我使用以下库在jdk7中使用PowerMock运行JUnit案例:
cglib-nodep-2.2.2.jar
javassist-3.19.0-GA.jar
junit-4.12.jar
mockito-all-1.10.19.jar
objenesis-2.1.jar
powermock-mockito-1.6.2-full.jar
以下是我使用PowerMock
的单元测试的代码片段@RunWith(PowerMockRunner.class)
@PrepareForTest(ValidateBindingImpl.class)
public class ValidateBindingImplTest{
//more code follows
}
执行此测试用例时,我收到以下错误:
java.lang.ClassFormatError: Invalid method Code length 119842 in class file com/v1/ValidateBindingImpl
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.lang.ClassLoader.defineClass(ClassLoader.java:465)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:269)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:249)
at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:95)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:107)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:31)
at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:370)
at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:351)
at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:653)
at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:460)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:286)
at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:222)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:69)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:52)
at java.lang.Class.initAnnotationsIfNecessary(Class.java:3079)
at java.lang.Class.getAnnotation(Class.java:3038)
at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:52)
at org.junit.internal.runners.TestClass.getAnnotatedMethods(TestClass.java:45)
at org.junit.internal.runners.MethodValidator.validateTestMethods(MethodValidator.java:71)
at org.junit.internal.runners.MethodValidator.validateStaticMethods(MethodValidator.java:44)
at org.junit.internal.runners.MethodValidator.validateMethodsForDefaultRunner(MethodValidator.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.<init>(PowerMockJUnit44RunnerDelegateImpl.java:70)
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:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:156)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.createDelegatorFromClassloader(JUnit4TestSuiteChunkerImpl.java:40)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.createTestDelegators(AbstractTestSuiteChunkerImpl.java:244)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:61)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
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:29)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
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:26)
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:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
发现类似帖子讨论了here和here,我尝试在VM参数中添加-XX:-UseSplitVerifier,但它没有用。
此外,我理解错误似乎是由于我的类文件中的冗长方法而发生的,但由于我的组织代码我无法修改/拆分方法,如某些在线帖子所示。
答案 0 :(得分:7)
您面临以下issue:JVM在bites中限制了方法大小,但在字节代码转换期间,为了使模拟静态成为可能,方法的最终大小可能超过此限制。在这种情况下,您会看到此错误
java.lang.ClassFormatError: Invalid method Code length 119842 in class file
在下一个版本中将包含修复,它通过代码默认抛出异常来替换巨大的方法来解决这个问题,但你仍然可以抑制这样的方法。
但是,对于无法修改的类,它仍然只是解决方法。解决问题的正确方法是重构代码以使方法更小。有很多重构技术可以实现这一目标。
答案 1 :(得分:1)
要使用JVM选项'-noverify':https://bugs.eclipse.org/bugs/show_bug.cgi?id=435446
答案 2 :(得分:0)
您可能不喜欢我的回答,但唯一合理的答案是:停止使用PowerMock。
如果您的生产代码需要PowerMock才能编写单元测试;那么认真:改变你的生产代码。如果你需要PowerMock,那么你的“被测代码”很可能是:糟糕。
PowerMock(以及所有其他依赖字节代码操作的模拟框架)最常引起麻烦而不是好事。他们会引起你现在所遇到的问题;它们极大地限制了您使用不同JVM或运行覆盖工具的能力。
这来自一个花费无数个小时来修复基于“PowerMock”的单元测试的人;在过去的几个月里,谁只依靠EasyMock编写了数百个单元测试;而且没有一次需要转向PowerMock。
答案 3 :(得分:0)
如前所述,这不仅可以通过尝试检测大型方法来实现,而且可以尝试使用大量方法来插入类。
我在around +/- 1500 methods
遇到了休息。这取决于类中的方法签名。
尝试减少类中的方法数量。