Java Mockito JUnit 测试/模拟类,其构造函数包含抽象方法调用

标签 java unit-testing junit mocking mockito

我有一个关于单元测试和模拟测试的问题。 我想测试一个与其他模块有依赖关系的模块。 问题是,我通过测试运行收到此消息:

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/

相关文章:

python - 有人知道 nosetest 的 -m、-i 和 -e 是如何工作的吗?

java - 如何在安全管理器策略文件中为可变父目录授予文件读/写权限

java - TDD:测试用例的适用性

java - 是否有一个 RDD 变换函数可以查看相邻元素?

java - 更改jdk版本的问题

java - 如何将请求 header 添加到基于 Tyrus 注释的客户端

python - 使用 Python unittest 模拟 side_effect

java - Swing - 启动浏览器并在用户关闭时收听

java - 抽象类中的模拟时钟抛出 NullPointerException

java - 无法使用 hibernate 通过 uniqueConstraintException 的 junit 测试