PowerMock + Mockito VS Mockito Alone

2022-08-31 15:40:37

任何人都可以总结一下,究竟是什么功能让你在Mockito之上添加了PowerMock?

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

  • 模拟静态、最终和私有方法
  • 删除静态初始值设定项
  • 允许在没有依赖注入的情况下进行模拟 - 这个对我来说并不清楚。你能详细说说吗?

它是否添加了其他内容?您能用几行来总结一下吗?

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


答案 1

我不知道其他好处,但我想解决你的2个子问题(这太长了,无法发表评论):

允许在没有依赖注入的情况下进行模拟 - 这个对我来说并不清楚。你能详细说说吗?

我认为这来自动机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可能发生的潜在可怕的事情是,为了完成模拟私有和静态方法的壮举,他们正在使用自定义类加载器(不应该在生产环境中的运行时出现)并更改类的字节码。可以说,对于大多数时候的类来说,这应该无关紧要,但是如果你仔细想想,如果字节码已经改变,并且某些副作用不再存在,那么你实际上是在根据你现有的类测试不同的类albiet。是的,这是一个非常学术的论点。

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

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


答案 2

PowerMock是Mockito的扩展,允许模拟静态方法,构造函数,最终类和方法,私有方法,删除静态初始值设定项等。


推荐