【问题标题】:Stubbing or mocking static methods in Java with Spock使用 Spock 在 Java 中存根或模拟静态方法
【发布时间】:2019-07-03 13:03:54
【问题描述】:

是否可以使用 spock 在 java 中模拟静态方法?我知道可以模拟静态 groovy 方法,但不能让它对 Java 方法起作用。

【问题讨论】:

  • 在 java 类中监视静态方法并不是 spock 本身支持的。重构不是你的选择吗?
  • 重构不是一种选择

标签: java spock


【解决方案1】:

没有。为此,您需要 PowerMockito。重构类或将静态调用包装在受保护的方法中并将其作为间谍存根。

【讨论】:

  • 正确答案。 :-) 此外,IMO 对 PowerMock (PM) 的需求是一种代码味道。所以我总是建议重构或包装而不是使用 PM,但对于它的价值,my answer here 展示了如何使用 Spock 的 PM。
【解决方案2】:

首先,这个问题的最佳/最差解决方案之一是 Powermock。是的,Powermock 将使您能够模拟静态方法。你嘲笑这个方法,你的测试通过了,你完全觉得你刚刚登陆月球(开玩笑)。我将是第一个承认我对这种做法 100% 有罪的人,我应该因为我缺乏思考而受到严厉的判决。

您通过使用 Powermock 模拟静态方法实际完成了什么?

您正在延续一种反模式,这种模式可能已经在您正在开发的任何应用程序中大量存在。这样做的许多负面影响之一是其他开发人员会进来,查看此代码并认为可以在他们正在处理的任何用例中继续实施此解决方案。

我的看法是这样的。我从模拟静态方法开始,但感觉从来都不是正确的。在您开始编写测试之前进行过多的设置和配置。

我发现,只需创建一个帮助类,我就可以在被测类中注入一个模拟(取决于您的情况),并使用返回静态实例方法所做的类型的方法,将允许我模拟该方法,因此避免使用 Powermock。此外,此用例中的生产代码不受影响。

到目前为止,我现在 100% 都在使用 Spock,但同样的原理可以用 JUnit 来完成。

如果您发现自己在应用程序中依赖 Powermock,请考虑消除这种依赖关系。这是实际上为问题提供解决方案的最糟糕的开源库之一,但它从未解决并提出解决问题根本原因的方法。

【讨论】:

  • 这是我去年评论的更详细的版本。我几乎完全同意,只有一个小细节需要解释。你说,“这个用例中的生产代码不受影响”。好吧,这是因为您需要通过调用包装类来重构和替换所有直接的静态方法调用,如果它不是单例或者从工厂方法中获取它,则可能还要实例化它,然后再闻起来很“静态”。也许您想用一些真实或伪代码详细说明那里使用的设计模式。然后通知我,我将删除或更改我的评论。 :-)
  • 是的,实际上我在 kriegaex cmets 上得到了纠正。在生产环境中,对辅助方法的调用实际上会执行真正的静态方法。在单元测试用例中,将返回模拟。
  • 无论如何,您的建议是有道理的,如果您有良好的覆盖率,那么在不改变功能的情况下进行重构以获得更好的设计是测试帮助您无所畏惧地做的事情。无论如何,自动化测试主要是一种设计工具,IMO。使用现代 IDE 进行重构从未如此简单,尤其是 IntelliJ IDEA 的结构搜索和替换等复杂功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多