示例代码:
class MyClass {
public void myMethod(Request request) {
Item item = getItem();
ItemUtilHelper.setCertainProperties(newProperty, item);
differentClass.staticMethod(item);
}
}
ItemUtilHelper
已经有一个单元测试类来验证项目是否已正确更新。
如何使用更新的differentClass.staticMethod
参数进行item
调用的单元测试?
答案 0 :(得分:5)
首先让我说静态方法本身就是代码气味。 Miško Hevery summed up it quite nicely by saying:
静态方法的基本问题是它们是程序代码。我不知道如何对程序代码进行单元测试。单元测试假设我可以单独实例化我的应用程序。
如果您只想使用Mockito,您的问题无法解决:
Mockito有哪些限制
Mockito 2.x特定限制
...
无法模拟静态方法
...
(见Mockito FAQ)
您可以使用PowerMock来实现目标。 但请注意:PowerMock在字节码级别上运行。这意味着
如果您仍想继续,那么您正在寻找的是间谍。您可以在PowerMock's wiki找到教程。虽然没有直接相关,但this question的答案给出了一些关于如何创建类的间谍的其他示例。整个示例可以在Automation Rhapsody上找到。
答案 1 :(得分:1)
除了@Turing85所说的最好将static
方法重构为public
非静态方法。然后,具有这种方法的对象可以作为参数传递给方法或构造函数,从而容易模拟或监视。通过这样做,您可以轻松地测试您的方法逻辑,并且不必担心对象依赖性,此时您不想测试哪些功能。
答案 2 :(得分:0)
看到您测试这种有效的操作有多痛,您是否考虑过应用功能范例?
静态方法没有气味。恰恰相反。如void
关键字所示,带有副作用的方法是该代码片段的臭味。这些方法通常很难测试和理解(正如你所注意到的那样)。在处理效果时,请考虑返回有意义的值(例如,可能是Try
或Future
,具体取决于您的方法的作用;请查看vavr)。也就是说,将副作用与以功能方式处理它的数据结构交换(关键字在函数编程的上下文中是有效编程)。并且不要改变状态(你的Item
)。而是使用不可变数据结构并返回具有更新值的新实例(您可以使用镜头)。
你最终得到的是一堆函数,它们返回的值仅取决于它们的参数。此功能称为引用透明度:无论计算上下文如何,您都可以通过其值替换该函数的每个调用。显示此功能的功能称为 pure 。然后,您可以轻松地在单元测试中定义断言而不传递任何模拟。