62

谁能总结一下,究竟是什么功能让您在 Mockito 之上添加了 PowerMock?

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

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

它是否添加了其他任何东西?你能概括几行吗?

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

4

5 回答 5

57

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

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

我认为这来自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 已经在项目中可用,您可能会想模拟它并继续前进,这将减轻应该鼓励您重构相同的痛苦。是的,有时由于各种技术和非技术限制,这是不可能的,但它'

于 2011-06-17T12:57:26.863 回答
12

PowerMock是 Mockito 的扩展,它允许模拟静态方法、构造函数、最终类和方法、私有方法、删除静态初始化程序等。

于 2016-08-09T00:15:34.203 回答
6

Powermock mockito 扩展的另一个特性是它支持对 equals 和 hashcode 进行模拟和存根

与所有要谨慎使用的 powermock 功能一样,但为特定结果添加(基于值的)相等性可能会有所帮助。

于 2012-03-07T08:07:04.170 回答
4

PowerMock 的另一个特性是我们可以在方法中模拟新对象的构造。当我们无法更改要测试的方法的代码时,它会很有帮助。

于 2015-10-07T08:36:56.067 回答
1

对于模拟最终类,我们可以使用org.mockito.plugins.MockMaker. 你需要做的是

  1. 在您的文件夹中创建一个test/resource名为的文件夹mockito-extensions
  2. 在其下创建一个名为org.mockito.plugins.MockMaker.
  3. 在那个文件中只有一行mock-maker-inline

这将不需要您添加任何新库,从而节省一些运行时间。

于 2019-04-05T19:58:46.023 回答