单元测试传递给静态方法的值

时间:2018-06-16 22:17:52

标签: java unit-testing mockito static-methods

示例代码:

class MyClass {
    public void myMethod(Request request) {
        Item item = getItem();
        ItemUtilHelper.setCertainProperties(newProperty, item);
        differentClass.staticMethod(item);
    }
}

ItemUtilHelper已经有一个单元测试类来验证项目是否已正确更新。

如何使用更新的differentClass.staticMethod参数进行item调用的单元测试?

3 个答案:

答案 0 :(得分:5)

首先让我说静态方法本身就是代码气味。 Miško Hevery summed up it quite nicely by saying:

  

静态方法的基本问题是它们是程序代码。我不知道如何对程序代码进行单元测试。单元测试假设我可以单独实例化我的应用程序。

如果您只想使用Mockito,您的问题无法解决:

  

Mockito有哪些限制

     

Mockito 2.x特定限制

     
      
  • ...

  •   
  • 无法模拟静态方法

  •   
  • ...

  •   

(见Mockito FAQ

您可以使用PowerMock来实现目标。 但请注意:PowerMock在字节码级别上运行。这意味着

  • 您可能没有测试在生产中使用的完全相同的字节码(比如问候Heisenbugs)和
  • 这可以与其他工具一起使用,例如: JaCoCo

如果您仍想继续,那么您正在寻找的是间谍。您可以在PowerMock's wiki找到教程。虽然没有直接相关,但this question的答案给出了一些关于如何创建类的间谍的其他示例。整个示例可以在Automation Rhapsody上找到。

答案 1 :(得分:1)

除了@Turing85所说的最好将static方法重构为public非静态方法。然后,具有这种方法的对象可以作为参数传递给方法或构造函数,从而容易模拟或监视。通过这样做,您可以轻松地测试您的方法逻辑,并且不必担心对象依赖性,此时您不想测试哪些功能。

答案 2 :(得分:0)

看到您测试这种有效的操作有多痛,您是否考虑过应用功能范例?

静态方法没有气味。恰恰相反。如void关键字所示,带有副作用的方法是该代码片段的臭味。这些方法通常很难测试和理解(正如你所注意到的那样)。在处理效果时,请考虑返回有意义的值(例如,可能是TryFuture,具体取决于您的方法的作用;请查看vavr)。也就是说,将副作用与以功能方式处理它的数据结构交换(关键字在函数编程的上下文中是有效编程)。并且不要改变状态(你的Item)。而是使用不可变数据结构并返回具有更新值的新实例(您可以使用镜头)。

你最终得到的是一堆函数,它们返回的值仅取决于它们的参数。此功能称为引用透明度:无论计算上下文如何,您都可以通过其值替换该函数的每个调用。显示此功能的功能称为 pure 。然后,您可以轻松地在单元测试中定义断言而不传递任何模拟。