为什么PowerMock使用javassist libraray和Mockito不使用

时间:2018-09-07 11:35:18

标签: mockito powermock

我不明白为什么PowerMock使用javassist库而不使用Mockito。

1 个答案:

答案 0 :(得分:2)

关于Java中代码生成库的大多数讨论都围绕着三个库:cglib,javassist和ByteBuddy。 Mockito以前在cglib上,但现在使用ByteBuddy作为其默认代码生成器。

正如ByteBuddy的作者Rafael Winterhalter notes here

  

javassist提供了一个API,用于修改类,而不仅用于子类化。这些API还允许进行字节代码级的操作,而cglib仅允许进行几种硬编码的拦截。

尽管我不是所有这些模拟框架或库的贡献者,但值得注意的是Powermock的工作方式部分是通过编辑类实现来拦截对已编译字节码中私有,静态和最终方法和类的调用。这可能解释了使用Powermock中的javassist的要求:cglib无法编辑现有类。相反,Mockito需要更简单的代码生成才能生成给定类的子类。这是cglib和ByteBuddy所提供的功能。

请注意,open Powermock issue 727跟踪了Powermock从Javassist到ByteBuddy的不完全迁移。

现在,相反:为什么Mockito不切换到Javassist而不是ByteBuddy?同样,我们没有直接答案,但是the ByteBuddy tutorial expresses an opinion(在Javassist的“一般信息”下,重点是我的):

  

该库带有一个编译器,该编译器使用包含Java源代码的字符串,这些字符串在应用程序运行时会转换为Java字节代码。因为Java源代码显然是描述Java类的一种很好的方法,所以这是非常雄心勃勃的,并且从原则上讲是个好主意。 但是,Javassist编译器在功能上无法与javac编译器相提并论,并且在动态组成字符串以实现更复杂的逻辑时容易出错。此外,Javassist附带了一个类似于Javassist的代理库。 JCL的代理实用程序,但允许扩展类,并且不限于接口。 Javassist代理工具的范围仍然受到其API和功能的限制。

简而言之:有很多轶事理由怀疑Javassist的安全性/功能性/稳定性。 Mockito不需要Javassist的功能,因此它可以直接从cglib迁移到ByteBuddy。 PowerMock确实需要Javassist的功能,而将PowerMock迁移到ByteBuddy的努力却停滞不前。