PowerMock + Mockito VS Mockito一个人

Vla*_*sny 51 java mocking mockito powermock

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

到目前为止,我发现了这些:

  • 模拟静态,最终和私有方法
  • 删除静态初始化程序
  • 允许在没有依赖注入的情况下进行模拟 - 这一点对我来说并不清楚.你能详细说说吗?

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

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

Cha*_*lie 50

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

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

我认为这来自Motivation wiki页面,它描述了一种重构代码的方法,即不调用静态方法使其可测试.对于我认为他们正在进行的具体示例,假设你有这个代码,并且你想测试模拟静态方法行为的方法,而不使用powermock:

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

一种解决方案是将静态调用拉入其自己的对象,然后注入一个可以在测试时进行模拟的对象.例如,不使用其他框架,这可能看起来像:

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();
         ...
     }
}
Run Code Online (Sandbox Code Playgroud)

我已经从静态调用的行为中分离了我的方法的行为,并且可以使用DI构造函数在测试时轻松地注入模拟.当然,对于powermock,我可以在适当的位置模拟静态方法,然后运行它.

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

身体上没有,但我会说哲学上是的:).以下是我的意见,我试图在他们背后给出充分的理由,但当然他们是意见所以请他们带着一点点盐:

PowerMock发生的潜在可怕事情是,为了完成模拟私有和静态方法的壮举,他们使用自定义类加载器(在生产中不应该出现在运行时)并更改类的字节码.可以说,大多数时候这对绝大多数类来说无关紧要,但是如果你考虑一下,如果字节码发生了变化,并且某些副作用不再存在,你就可以根据你的不同来有效地测试不同的类了.现有的类.是的,这是一个非常学术性的论点.

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

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

  • 我想总结一下父母关于使用PowerMock到**tl; dr**版本的警告:"重构,如果可能/允许是可取的;有PowerMock可能会阻止重构" (4认同)
  • 2)我仍然坚持拐杖的论点.没有什么可以阻止我使用`final`,`new`或`static` ...但是我的**意见**如果我选择使用它们,这些方法中的代码不应该需要模拟.如果它们是那么复杂或充满副作用,我可能应该考虑封装到其他对象中,这样我就可以在测试时或实现更改时注入模拟.(更不用说像[Guice](http://code.google.com/p/google-guice/)这样的DI框架"@Inject是新的":D) (3认同)

Pre*_*raj 7

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


ava*_*sen 6

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

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