我可以对使用java.lang.reflect.Constructor的类进行单元测试吗? (LocalVariableTable中的长度无效)

时间:2015-12-15 17:51:30

标签: java unit-testing reflection mockito powermockito

我试图对一些旧的遗留代码进行单元测试。我一直在使用Mockito,PowerMockito和Whitebox来测试私有和静态方法。我成功地测试了几个大型和毛茸茸的课程,但是我遇到了一个特定课程的问题。我认为这与这个类扩展的类有关。父类(AjaxEnabledModule)使用java.lang.reflect.Constructor,如下所示:

public AjaxEnabledForm getForm(AjaxEnabledFormType formType) {
 if (!this.forms.containsKey(formType)) {
  Class<?>[] classesParameter = new Class<?>[] { AjaxEnabledModule.class };
  Object[] valuesParameter = new Object[] { this };
  Class<? extends AjaxEnabledForm> clazz = formType.getFormClass();
  try {
    Constructor<? extends AjaxEnabledForm> constructor = clazz.getConstructor(classesParameter);
    setForm(constructor.newInstance(valuesParameter));
  }
  catch (NoSuchMethodException e) {
    Logger.getLogger(getClass()).error("Invalid constructor for: " + clazz.getCanonicalName());
  }
  catch (IllegalArgumentException e) {
    Logger.getLogger(getClass()).error(
        "Invalid argument(s): " + classesParameter + " for Constructor: " + clazz.getCanonicalName());
  }
  catch (InstantiationException e) {
    Logger.getLogger(getClass()).error("Unable to instantiate new Form: " + clazz.getCanonicalName());
  }
  catch (IllegalAccessException e) {
    Logger.getLogger(getClass()).error("Constructor for: " + clazz.getCanonicalName() + " is not accessable");
  }
  catch (InvocationTargetException e) {
    Logger.getLogger(getClass()).error("Invalid Invocation Target for Constructor: " + clazz.getCanonicalName());
  }
}
return this.forms.get(formType);
}

我只是猜测这是问题所在,因为父类中没有其他事情发生。我没有尝试直接测试父类的功能,但我无法测试子类中的任何内容。我无法运行使用@RunWith(PowerMockRunner.class)的任何测试并收到此错误:

java.lang.ClassFormatError: Invalid length 3526 in LocalVariableTable in class file resultsreview/base/AjaxEnabledModule
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:630)
at java.lang.ClassLoader.defineClass(ClassLoader.java:614)
at java.lang.ClassLoader.defineClass(ClassLoader.java:464)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:268)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:179)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:246)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:630)
at java.lang.ClassLoader.defineClass(ClassLoader.java:614)
at java.lang.ClassLoader.defineClass(ClassLoader.java:464)
at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:268)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:179)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:246)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
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:3070)
at java.lang.Class.getAnnotation(Class.java:3029)
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 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: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)

我在使用旧版本的javassist时看到其他帖子收到类似错误。我正在使用javassist-20但删除了它,我仍然收到此错误。我非常喜欢继续使用PowerMockito,因为这是我熟悉的。有谁知道如何修复此错误或知道另一个框架没有使用可以模拟私有和静态方法的PowerMockRunner?

版本: -Java 6 - PowerMock罐子版本1.6.3
- Mockito版本1.10.19。

(我使用的是Javassist-20,但完全删除了它,但仍然收到错误。)

不幸的是,我还应该说这不是Maven项目。我正在使用Eclipse,我在构建路径中看不到对javassist的任何引用或进行文件搜索。

1 个答案:

答案 0 :(得分:0)

我以为我会回来更新这个问题。我发现我不能使用PowerMockito来测试使用反射的类(或者从使用反射的类继承)。除了如果我想要进行单元测试而将父类重新分解为不使用反射,我不会认为它有任何解决方法。

另一个更新:一旦我们将旧项目转换为Maven项目,我就能够成功测试这个类。我不知道为什么,但我不再在Maven项目中得到上述错误。