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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4482315/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:56:24  来源:igfitidea点击:

Why doesn't Mockito mock static methods?

javamethodsstaticmockito

提问by Abidi

I read a few threads here about static methods, and I think I understand the problems misuse/excessive use of static methods can cause. But I didn't really get to the bottom of why it is hard to mock static methods.

我在这里阅读了一些关于静态方法的主题,我想我理解误用/过度使用静态方法可能导致的问题。但是我并没有真正了解为什么很难模拟静态方法。

I know other mocking frameworks, like PowerMock, can do that but why can't Mockito?

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

I read this article, but the author seems to be religiously against the word static, maybe it's my poor understanding.

我读了这篇文章,但作者似乎对这个词很反感static,也许是我的理解不足。

An easy explanation/link would be great.

一个简单的解释/链接会很棒。

采纳答案by Matthias

I think the reason may be that mock object libraries typically create mocks by dynamically creating classes at runtime (using cglib). This means they either implement an interface at runtime (that's what EasyMock does if I'm not mistaken), or they inherit from the class to mock (that's what Mockito does if I'm not mistaken). Both approaches do not work for static members, since you can't override them using inheritance.

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

The only way to mock statics is to modifya class' byte code at runtime, which I suppose is a little more involved than inheritance.

模拟静态的唯一方法是在运行时修改类的字节码,我认为这比继承要复杂一些。

That's my guess at it, for what it's worth...

这是我的猜测,因为它的价值......

回答by Tyler Treat

In some cases, static methods can be difficult to test, especially if they need to be mocked, which is why most mocking frameworks don't support them. I found thisblog post to be very useful in determining how to mock static methods and classes.

在某些情况下,静态方法可能难以测试,尤其是当它们需要被模拟时,这就是大多数模拟框架不支持它们的原因。我发现这篇博文对于确定如何模拟静态方法和类非常有用。

回答by Jan

If you need to mock a static method, it is a strong indicator for a bad design. Usually, you mock the dependency of your class-under-test. If your class-under-test refers to a static method - like java.util.Math#sin for example - it means the class-under-test needs exactly this implementation (of accuracy vs. speed for example). If you want to abstract from a concrete sinus implementation you probably need an Interface (you see where this is going to)?

如果你需要模拟一个静态方法,它是一个糟糕设计的有力指标。通常,您会模拟被测类的依赖项。如果您的被测类指的是静态方法 - 例如 java.util.Math#sin - 这意味着被测类正是需要这种实现(例如准确性与速度)。如果你想从一个具体的窦性实现中抽象出来,你可能需要一个接口(你知道这是要去哪里)?

回答by pete83

I seriously do think that it is code smell if you need to mock static methods, too.

如果您也需要模拟静态方法,我确实认为这是代码异味。

  • Static methods to access common functionality? -> Use a singleton instance and inject that
  • Third party code? -> Wrap it into your own interface/delegate (and if necessary make it a singleton, too)
  • 访问常用功能的静态方法?-> 使用单例实例并注入它
  • 第三方代码?-> 将其包装到您自己的界面/委托中(如有必要,也将其设为单例)

The only time this seems overkill to me, is libs like Guava, but you shouldn't need to mock this kind anyway cause it's part of the logic... (stuff like Iterables.transform(..))
That way your own code stays clean, you can mock out all your dependencies in a clean way, and you have an anti corruption layer against external dependencies. I've seen PowerMock in practice and all the classes we needed it for were poorly designed. Also the integration of PowerMock at times caused serious problems
(e.g. https://code.google.com/p/powermock/issues/detail?id=355)

唯一一次对我来说这似乎有点矫枉过正,是像 Guava 这样的库,但无论如何你都不应该嘲笑这种类型,因为它是逻辑的一部分......(像 Iterables.transform(..)
这样的东西)那样你自己的代码保持干净,您可以以干净的方式模拟所有依赖项,并且您有一个针对外部依赖项的反腐败层。我在实践中见过 PowerMock,我们需要它的所有类都设计得很差。此外,PowerMock 的集成有时会导致严重的问题
(例如https://code.google.com/p/powermock/issues/detail?id=355

PS: Same holds for private methods, too. I don't think tests should know about the details of private methods. If a class is so complex that it tempts to mock out private methods, it's probably a sign to split up that class...

PS:私有方法也是如此。我认为测试不应该知道私有方法的细节。如果一个类是如此复杂以至于它试图模拟私有方法,那么这可能是拆分该类的标志......

回答by salsinga

Mockito returns objects but static means "class level,not object level"So mockito will give null pointer exception for static.

Mockito 返回对象,但静态意味着“类级别,而不是对象级别”,因此 mockito 将为静态提供空指针异常。