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

Java 在这种情况下,人们如何编写单元测试,java,unit-testing,mocking,Java,Unit Testing,Mocking,我有一个关于单元测试的问题 我将测试一个模块,它是web服务的适配器。测试的目的不是测试web服务,而是测试适配器 服务提供的一个函数调用如下所示: class MyAdapterClass { WebService webservice; MyAdapterClass(WebService webservice) { this.webservice = webservice; } void myBusinessLogic() { List<VeryC

我有一个关于单元测试的问题

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

服务提供的一个函数调用如下所示:

class MyAdapterClass {

  WebService webservice;

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

  void myBusinessLogic() {
    List<VeryComplicatedClass> result = webservice.getResult();
    // <business logic here>
  }
}
类MyAdapterClass{
WebService-WebService;
MyAdapterClass(Web服务Web服务){
this.webservice=webservice;
}
void myBusinessLogic(){
List result=webservice.getResult();
// 
}
}
如果我想对myBusinessLogic函数进行单元测试,通常的方法是使用
getResult()
函数设置为某个预定义的返回值注入模拟版本的webservice

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

如果我打算使用Mockito或类似的东西手动设置一个结果,这将是一个巨大的工作量

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


非常感谢。

您可以编写代码来调用真正的web服务,然后将
列表
序列化到磁盘上的文件,然后在模拟的设置中对其进行反序列化,并让
mockwebservice.getResult()
返回该对象。这将节省您手动构建对象层次结构的时间

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



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

您可以编写代码来调用真正的web服务,然后将
列表序列化到磁盘上的文件,然后在设置中进行设置您的模拟将其反序列化,并让
mockwebservice.getResult()
返回该对象。这将节省您手动构建对象层次结构的时间

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



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

我在阅读注释时想到的一个想法是引入一个新的接口,它可以包装
列表,并使myBusinessLogic可以使用那倒是


然后就可以很容易地(/更容易地)存根或模拟新接口的实现,而不是处理一个你几乎无法控制的非常复杂的类。

我读到这些评论的一个想法是引入一个新接口,它可以包装
列表
,并让myBusinessLogic使用它


然后,就可以很容易地(/更容易地)存根或模拟新接口的实现,而不是处理一个您几乎无法控制的非常复杂的类。

只运行一次Web服务。保存输出,并将该输出用作模型的基础。感谢您的回复。我明白了。但是,VeryCompletedClass不在我的控制范围内,它是不可序列化的。如何保存普通对象?无法保存普通对象。您可以从VeryComplicatedClass中获取所有带有公共getter的字段,并将其放入一个可序列化的类中,然后将其写出(稍后读入)。保存输出,并将该输出用作模型的基础。感谢您的回复。我明白了。但是,VeryCompletedClass不在我的控制范围内,它是不可序列化的。如何保存普通对象?无法保存普通对象。您可以将所有带有公共getter的字段从VeryComplicatedClass获取到一个可序列化的类中,然后将其写出(稍后阅读)。感谢您的回复。我明白了。但是,VeryCompletedClass不在我的控制范围内,它是不可序列化的。如何保存普通对象?如果可能,您最好按照答案第二部分建议的路线进行。谢谢您的回复。我明白了。但是,VeryCompletedClass不在我的控制范围内,它是不可序列化的。如何保存普通对象?如果可能,您最好按照答案第二部分建议的路线进行操作。