为什么Mockito不能模拟静态方法?

我在这里读了几个关于静态方法的线程,我想我明白滥用/过度使用静态方法会导致的问题。 但是我没有真正明白为什么很难嘲讽静态方法。

我知道其他嘲笑的框架,如PowerMock,可以做到这一点,但为什么不能Mockito?

我读过这篇文章 ,但作者似乎对static这个词虔诚,也许这是我的不理解。

一个简单的解释/链接将是伟大的。

我认为原因可能是模拟对象库通常通过在运行时dynamic创build类(使用cglib )创build模仿。 这意味着他们要么在运行时实现一个接口(这就是EasyMock如果我没有弄错的话),或者他们从类inheritance来模拟(这是Mockito如果我没有弄错的话)。 这两种方法不适用于静态成员,因为您不能使用inheritance覆盖它们。

模拟静态的唯一方法是在运行时修改一个类的字节码,我认为这比inheritance更复杂一点。

这是我的猜测,值得…

如果你需要模拟一个静态方法,这是一个糟糕的devise强烈的指标。 通常,你嘲笑你的类testing的依赖性。 如果被testing的类引用了一个静态方法 – 比如说java.util.Math#sin,那么它就意味着待测类正好需要这个实现(比如精确度和速度)。 如果你想从一个具体的窦实现抽象,你可能需要一个接口(你会看到这个将要去的地方)?

我认真地认为,如果你也需要模拟静态方法的话,这是代码味道。

  • 静态方法来访问常见的function? – >使用一个单例实例并注入
  • 第三方代码? – >把它包装到你自己的接口/委托(如果有必要,也使它成为一个单身人士)

对我来说似乎有点矫枉过正的是像番石榴一样的库,但是你不应该嘲笑这种types,因为它是逻辑的一部分…(像Iterables.transform(..)这样的东西)
这样,你自己的代码保持干净,你可以用干净的方式模拟出你所有的依赖关系,并且你有一个防止外部依赖的反腐败层。 我已经看到PowerMock在实践中,我们需要的所有类都devise得很差。 有时PowerMock的整合也造成了严重的问题
(例如https://code.google.com/p/powermock/issues/detail?id=355

PS:私人方法也一样。 我不认为testing应该知道私有方法的细节。 如果一个class级如此复杂以至于试图嘲笑私人方法,那么这可能是划分class级的标志。

Mockito返回对象,但静态意味着“类级别,而不是对象级别”因此,mockito会给静态的空指针exception。

在某些情况下,静态方法可能难以testing,特别是如果需要嘲笑的话,这就是大多数嘲讽框架不支持它们的原因。 我发现这个博客文章在确定如何模拟静态方法和类时非常有用。