【发布时间】:2014-09-01 07:04:37
【问题描述】:
这不仅仅是一个实际案例,这是我在尝试详细了解单元测试和集成测试之间的区别时遇到的一个问题。
假设我有一个 Sum 类,它将两个整数相加:
class Sum{
int x;
int y;
public int add(){
return x + y;
}
...getters and setters...
}
我还有另一个班级负责验证结果,以确认这些值是预期的。举个例子,假设我们只想添加正数:
class ValidateSum{
Sum sum;
public boolean validate(){
if(sum.getX()>=0 and sum.getY()>=0){
return true;
}
else{
return false;
}
}
... getters and setters...
}
可能拥有 ValidateSum 并没有多大意义,但我们只是为了示例而假设它。
现在我想为 ValidateSum 编写测试。如果我这样做:
@Test
public void testValidateSum(){
ValidateSum vs = new ValidateSum();
Sum sum = new Sum();
vs.setSum(sum);
boolean result = vs.validate();
assertTrue(result);
}
这是单元测试还是集成测试?
我知道单元测试只需要验证 ValidateSum 中的功能,并且测试在某种程度上是这样做的:它只从 Sum 中获取属性,而不是真正的任何功能。
但另一方面,您也可以说您确实正在从 Sum 访问功能,即使 ValidateSum 只调用一个 getter。 Sum 的 getter 的任何更改都会影响 ValidateSum 的测试,从而破坏了单元测试的概念。
但是如果是这种情况并且确实是集成测试,那么我该如何为 ValudateMethod 的 validate() 编写单元测试?
我唯一想不到的是模拟 Sum,所以它总是返回相同的值。即使 Sum 的 getter 内部的逻辑发生变化,ValidateSum 的测试也会保持不变。问题是,模拟 getter 的响应可能会增加不必要的复杂性,因为更改 getter 内部逻辑的可能性非常低,而我们所做的只是获取一个属性。
我希望我的问题是有道理的,这更像是一个理论上的疑问。
编辑
感谢您的回答。他们有重要的事情要记住。我选择了一个作为最佳答案的答案是因为它让我想到了这一点:
http://www.mockobjects.com/2007/04/test-smell-everything-is-mocked.html
这是真的:理论上我必须模拟 Sum,这样它就变成了一个纯粹的单元测试。但在大多数情况下,增加的复杂性成本和模拟属性 getter 所花费的努力并不值得仅仅为了获得“最纯粹的”单元测试,而实际上对于这种情况,单元测试和集成测试之间的差异是主观的。
【问题讨论】:
-
这是一个单元测试,但 ValidateSum 与 Sum 紧密耦合。如果其中一个发生变化(如 Sum),那么您还必须更改
ValidateSum。事实上,ValidateSum应该是你的 jUnit 类中的一个函数。
标签: java unit-testing testing mocking integration-testing