为什么 PowerMock 使用 javassist libraray 而 Mockito 没有使用

Why PowerMock use javassist libraray and Mockito is not use

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

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

作为 ByteBuddy 作者 Rafael Winterhalter notes here:

javassist offers an API for modifying classes and not only for subclassing them. These APIs allow also for byte code-level manipulation while cglib only allows for several hardcoded interceptions.

虽然我不是任何这些模拟框架或库的贡献者,但值得注意的是,Powermock 的部分工作是通过编辑 class 实现来拦截对私有、静态和最终方法的调用,并且 classes 在已编译的字节码中。这可能解释了使用 Powermock 中的 javassist 的要求:cglib 无法编辑现有的 classes。相比之下,Mockito 需要更简单的代码生成才能生成给定 class 的子 class;这是 cglib 和 ByteBuddy 被编写来提供的功能。

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

现在,反过来:为什么 Mockito 不切换到 Javassist 而不是 ByteBuddy?同样,我们没有直接的答案,但是 the ByteBuddy tutorial expresses an opinion(在 "General Information" 下 Javassist,强调我的):

This library comes with a compiler that takes strings containing Java source code which are translated into Java byte code during the runtime of an application. This is very ambitious and in principle a great idea since Java source code is obviously a great way for describing Java classes. However, the Javassist compiler does not compare to the javac compiler in its functionality and allows for easy mistakes when dynamically composing strings to implement more complex logic. Additionally, Javassist comes with a proxy library which is similar to the JCL's proxy utilities but allows extending classes and is not limited to interfaces. The scope of Javassist's proxy tools remain however equally limited in its API and functionality.

简而言之:有轶事理由怀疑 Javassist 的 safety/functionality/stability。 Mockito 不需要 Javassist 的功能,因此它可以直接从 cglib 迁移到 ByteBuddy。 PowerMock 确实需要 Javassist 的功能,将 PowerMock 迁移到 ByteBuddy 的工作已经停滞并正在进行中。