我对单元测试有疑问。
我将测试一个模块,它是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服务并再次测试真实的服务。有什么好事可做吗?
非常感谢。
答案 0 :(得分:4)
您可以编写代码来调用真实的Web服务,然后将List<VeryComplicatedClass>
序列化到磁盘上的文件,然后在模拟的设置中反序列化它并让mockwebservice.getResult()
返回该对象。这将节省您手动构建对象层次结构。
更新:这基本上是Gilbert在他的评论中提出的方法。
但实际上......你不想设置一个已完成的类列表,每个类都有几十个属性,列表可能包含数百甚至数千个元素,你想要设置一个模拟或存根,捕获围绕业务逻辑编写断言所需的最小值。这样,测试可以更好地传达它实际关心的细节。更具体地说,如果业务逻辑在VeryComplicatedClass
上调用2或3个方法,那么您希望测试是明确的,那些是测试断言所需的条件。
答案 1 :(得分:2)
有人认为我读过这些评论的意思是引入一个新的界面,它可以包裹List<VeryComplicatedClass>
并让myBusinessLogic使用它。
然后很容易(/更容易)存根或模拟新界面的实现,而不是处理一个你无法控制的非常复杂的类。