人们如何在这种情况下编写单元测试

时间:2012-04-18 19:23:19

标签: java unit-testing mocking

我对单元测试有疑问。

我将测试一个模块,它是Web服务的适配器。测试的目的不是测试Web服务,而是测试适配器。

一个函数调用服务提供就像:

class MyAdapterClass {

  WebService webservice;

  MyAdapterClass(WebService webservice) {
    this.webservice = webservice;
  }

  void myBusinessLogic() {
    List<VeryComplicatedClass> result = webservice.getResult();
    // <business logic here>
  }
}

如果我想对myBusinessLogic函数进行单元测试,通常的方法是为一些预定义的返回值注入一个带有getResult()函数设置的webservice的模拟版本。

但是我的问题是,真正的web服务将返回一个非常完整的类列表,每个类都有数十个属性,列表可能包含数百甚至数千个元素。

如果我要使用Mockito或类似的东西手动设置结果,那将是一项繁重的工作。

在这种情况下,人们通常会做些什么?我只是连接到真正的Web服务并再次测试真实的服务。有什么好事可做吗?

非常感谢。

2 个答案:

答案 0 :(得分:4)

您可以编写代码来调用真实的Web服务,然后将List<VeryComplicatedClass>序列化到磁盘上的文件,然后在模拟的设置中反序列化它并让mockwebservice.getResult()返回该对象。这将节省您手动构建对象层次结构。

更新:这基本上是Gilbert在他的评论中提出的方法。


但实际上......你不想设置一个已完成的类列表,每个类都有几十个属性,列表可能包含数百甚至数千个元素,你想要设置一个模拟或存根,捕获围绕业务逻辑编写断言所需的最小值。这样,测试可以更好地传达它实际关心的细节。更具体地说,如果业务逻辑在VeryComplicatedClass上调用2或3个方法,那么您希望测试是明确的,那些是测试断言所需的条件。

答案 1 :(得分:2)

有人认为我读过这些评论的意思是引入一个新的界面,它可以包裹List<VeryComplicatedClass>并让myBusinessLogic使用它。

然后很容易(/更容易)存根或模拟新界面的实现,而不是处理一个你无法控制的非常复杂的类。