Java 使用jmockit模拟私有/静态方法

Java 使用jmockit模拟私有/静态方法,java,unit-testing,junit,jacoco,jmockit,Java,Unit Testing,Junit,Jacoco,Jmockit,我试图使用jmockit 1.18来模拟静态方法,但我担心代码覆盖率。我得到的错误是: java.lang.instrument.IllegalClassFormatException:运行时出错 检测类org/junit/runner/notification/RunNotifier 我使用的是jacoco代理0.6.3.201306030806和EclEmma core 2.2.1.201306092145 我担心代码覆盖率 您几乎可以在任何允许模拟private/final类和static

我试图使用jmockit 1.18来模拟静态方法,但我担心代码覆盖率。我得到的错误是:

java.lang.instrument.IllegalClassFormatException:运行时出错 检测类org/junit/runner/notification/RunNotifier

我使用的是jacoco代理0.6.3.201306030806EclEmma core 2.2.1.201306092145

我担心代码覆盖率

您几乎可以在任何允许模拟
private
/
final
类和
static
/
private
/
final
成员的模拟框架中体验到这一点。原因是模拟框架在实际测试的运行时改变字节码,而覆盖工具在测试开始前改变字节码

更好的方法是更改代码,这样它就不会对成员使用静态访问,也不会使方法
成为final
(通常)。此外,如果您正确地实现关注点分离、单一责任、单层抽象*和依赖项注入,那么编写测试就更容易了。

较旧版本的JaCoCo(在链接页面中搜索“jmockit”)将与其他字节码修改工具(如jmockit)发生冲突

因此,如果您将EclEmma升级到使用jacoco0.7.3+的版本,就可以了

另一方面,
IllegalClassFormatException
指向JUnit的
RunNotifier
类,JMockit在运行时修改该类(出于集成目的),但JaCoCo不应该修改。因此,在这里,您可能需要将此类类从JaCoCo工具中排除(请参阅JaCoCo/EclEmma文档)。

而不是1)对某些技术问题的原因做出疯狂的假设,2)建议开发人员将其代码弯曲到特定测试工具的限制,3)推广糟糕的设计(由于正确使用
final
对于良好的API设计很重要——例如,请参阅“有效的Java”一书),以及4)四处散布流行语,您可能实际上可以尝试为手头的问题提供正确而有用的答案(例如,请参阅我的答案)…@Rogério 1)您能证明我错了吗?2) 通常,在测试代码时遇到问题,随着程序的增长,在重用/修改代码时通常也会遇到问题。顺便说一句:你不是也这么做了吗(只是为了测试代码)?3) 只有少数情况下,final是正确使用的。即使是通过“有效的java”的方式,将它放在没有特定原因的任何地方也是不合适的。4)它告诉你很多你认为重要的OO原则是“流行语”。1)是的,我可以证明你是错的,只要指出JMockit和雅各科,在最近的版本中,就可以一起工作(据我所知)。换句话说,这两种工具都“在运行时改变字节码”,这并不意味着它们不能协同工作。2)是的,可测试性(易于测试)与可维护性(易于修改/演化代码)基本相同。但是测试的简易性与方法是
final
private
static
,或者对象是直接用
new
实例化的,而不是注入的无关。3)在良好的API设计中(另请参见“实用API设计”和“针对C++的API设计”书籍)您将大多数类声明为
final
,因为它们不会被设计为用作基类。在设计基类时,通常有
受保护的
公共的
方法需要进行
最终的
(例如,当应用GoF书籍中的“模板方法”模式时)。“有效Java”在第17项中说“设计并记录继承或禁止继承”(意思是,默认情况下使类成为final)。