一尘不染

单独使用PowerMock + Mockito VS Mockito

java

谁能总结一下,究竟什么功能使您在Mockito的基础上添加了PowerMock?

到目前为止,我已经找到了这些:

  • 模拟静态,最终和私有方法
  • 删除静态初始化器
  • 允许在没有依赖项注入的情况下进行嘲笑-我不清楚这一点。你能详细说明吗?

它还会添加其他内容吗?您可以分几行进行总结吗?

使用PowerMock时需要牺牲一些东西吗?


阅读 208

收藏
2020-12-03

共1个答案

一尘不染

我不知道还有其他好处,但是我想解决您的两个子问题(这对于评论来说太长了):

允许在没有依赖项注入的情况下进行嘲笑-我不清楚这一点。你能详细说明吗?

我认为这来自Motivation
Wiki页面
,他们在其中描述了一种重构代码的方法,该方法不调用静态方法以使其可测试。对于我认为他们正在得到的东西的一个具体示例,假设您有这段代码,并且想要测试模拟静态方法行为的方法,而无需使用powermock:

public class MyClass {
     public void doGetString() {
         ...
         OtherClass.getString(); //It's complex and scary and needs mocking!
         ...
     }
}

一种解决方案是将静态调用拉入其自己的对象,然后注入一个可以在测试时模拟的对象。例如,在不使用其他框架的情况下,它可能类似于:

public class MyClass {
     public static class StringGetter {
         public getString() {
             return OtherClass.getString();                 
         }
     }

     private final StringGetter getter;

     //Existing Constructor
     public MyClass() {
         this(new StringGetter());
     }

     //DI Constructor
     MyClass(StringGetter getter) {
         this.getter = getter;
     }

     public void doGetString() {
         ...
         getter.getString();
         ...
     }
}

我已经将方法的行为与静态调用的行为分开了,并且可以使用DI构造函数在测试时轻松注入模拟。当然,使用powermock可以模拟静态方法,然后运行它。

使用PowerMock时需要牺牲一些东西吗?

身体上没有,但我会从哲学上说:)。以下是我的观点,我尝试给出充分的理由,但当然它们是观点,因此请带点盐:

PowerMock可能发生的令人恐惧的事情是,为了完成模拟私有方法和静态方法的壮举,他们使用了自定义类加载器(不应在生产时的运行时出现)并更改类的字节码。
。可以说,大多数情况下,这与大多数类无关紧要,但是如果您考虑一下,如果字节码已更改,并且不再出现某些副作用,那么您将根据自己的情况有效地测试不同的类现有课程。是的,这是一个非常学术性的争论。

您可以通过进行良好的全面集成和不使用PowerMock的更高级别的测试来缓解第一个争论。这样,即使您的单元测试使用PowerMock,您也可以对对象的行为更有信心。

我反对PowerMock的另一个论点是,它几乎太容易成为拐杖。我同意PowerMock可以帮助测试使用遗留代码和您无法控制的其他代码的代码。但是我认为,当您控制需要模拟的类时,应该避免使用它。如果您使用私有方法或静态方法编写一个类,而您需要显式模拟该类以测试其他方法,那么我的直觉会认为该方法可能做得太多,应该对其进行重构和分解。在项目中已经有PowerMock时,您可能会想去模拟它并继续前进,这将减轻应鼓励您对其进行重构的痛苦。是的,有时由于各种技术和非技术限制,这是不可能的,但是

2020-12-03