我有一个关于单元测试和模拟测试的问题。 我想测试一个与其他模块有依赖关系的模块。 问题是,我通过测试运行收到此消息:
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/component/UIComponent
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.privateGetPublicMethods(Unknown Source)
at java.lang.Class.getMethods(Unknown Source)
at org.mockito.internal.runners.util.TestMethodsFinder.hasTestMethods(TestMethodsFinder.java:13)
at org.mockito.internal.runners.RunnerFactory.create(RunnerFactory.java:33)
at org.mockito.runners.MockitoJUnitRunner.<init>(MockitoJUnitRunner.java:57)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
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)
例如:
public void MyMethod(){
PickList myPickList = new PickList();
... some code ...
myPickList.getSource();
myPickList.getTarget();
}
PickList 构造函数包含:
PickList(){setRendererType(rendererValue);}
方法setRendererType是一个扩展UIComponent的抽象方法。
我的问题是,如何测试/模拟(仅允许 Java 1.7、JUnit4 和 Mockito 1.10.19)此方法?
是否可以模拟/避免构造函数调用?
我可以模拟更深层次的依赖关系吗?
最佳答案
所以有一些事情。
首先,您可以使用 JMockit 或 Powermock 模拟构造函数调用。
其次,永远不要从构造函数中调用抽象方法。对于任何非 final方法也是如此。您永远不应该从构造函数中调用任何非最终实例方法。这是因为您在子类的构造函数完全执行之前调用子类的实例方法。因此,子类中可能存在由构造函数填充的实例字段。在调用实例方法(通过 super 构造函数调用)时,这些字段尚未填充,这违反了实例方法的预期。
更新:但是,看看您的问题,setRendererType
并不是 PickList
的抽象。它是 UIComponent
中的抽象方法,但 PickList
或某些父类必须实现它,因此对于 PickList
它不是抽象的。但是,有关非 final方法的规则仍然适用。
关于Java Mockito JUnit 测试/模拟类,其构造函数包含抽象方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28171512/