随着java 7&8当使用Mockito和PowerMockRunner时,当涉及静态最终变量时,Java会抛出一个错误字节码异常。这是由于现在更严格的字节码验证和模拟静态最终对象编辑字节码以成功模拟。
我有下面的课,我试图嘲笑:
public class ClassToBeMocked {
private static final int LIMIT_FROM_PROPERTIES = AnotherClazz.methodToRetrieveFromMap("String being called")
//more stuff
}
我已经看到,你可以通过使用反射来解决这个问题,这里看到了如何使用JUnit、EasyMock或PowerMock模拟静态最终变量,这里是PowerMock:模拟私有静态最终变量是一个具体的例子(不是一个很好的解决方案,但它应该可以工作)。然而,使用反射需要对象已经被实例化,并且我在尝试实例化ClassToBeMocked时得到了字节码异常。
我还试着在单元测试中嘲笑AnotherClazz.methodToRetrieveFromMap(String)(使用正确的语法):
Mockito.when( AnotherClazz.methodToRetrieveFromMap("String being called") ).thenReturn(10);
但是,这会再次导致字节码错误。
有没有办法绕过这个第二十二条军规,或者使用一个更好的不同框架或单元运行程序?
我认为没有反思就没有办法做到这一点。无论如何,我认为如果您需要更改static final
常量,那么您的设计中可能存在"错误",尽管您只需要用于测试范围。
正如你在问题中所说,PowerMock / EasyMock
有一些方法可以做到这一点,但无论如何,它们仍然是反思。
我将在其他答案中等待可能的替代方案。
我建议您考虑将生产代码更改为狂热使用的静态和最终代码。这些都是众所周知的可测试性杀手。当您试图伪造这些构造时,您遇到的字节码操作问题就是已知问题。
顺便说一句,确保你的PowerMock版本是最新的。还要确保您的Mockito版本与PowerMock相匹配。你可以在这里找到PowerMock版本矩阵。