unit-testing - EasyMock 的 .times(x) 方法是单元测试稳健性的问题吗?
问题描述
我目前正在使用 JUnit 和 EasyMock 为我的应用程序进行一些单元测试,以模拟复杂的对象,我正面临着两难境地。例如,我正在使用以下测试模板测试每个函数:
public static int foo(Object a){
// my function that needs to be tested
int quantity = 0;
if(a != null && a.getInt() != null ){
quantity = a.getInt();
}
return quantity;
}
public void testFoo(){
// my unit test for the function foo
int expectedValue = 0;
int output = 0;
//Setting up my mocks
Object a_mock = EasyMock.create(Object.class)
EasyMock.expect(a_mock.getInt()).andReturn(null).times(1);
EasyMock.expect(a_mock.getInt()).andReturn(1).times(2);
//Executing
// Case 1: a is null
expectedValue = 0;
output = foo(null);
assertEquals(expectedValue, output);
// Case 2: a.getIn() is null
expectedValue = 0;
output = foo(a_mock);
assertEquals(expectedValue, output);
//Case 3: nominal case
expectedValue = 1;
output = foo(a_mock);
assertEquals(expectedValue, output);
}
这个结构工作得很好,但我的观点是:单元测试是一个测试过程,它允许你验证每个单元(这里是一个函数)是否在知道输入的情况下给你想要的输出。这意味着如果我需要修改我的函数 foo,但不修改它的作用,我的单元测试仍然必须通过。理论上,如果 foo 像这样改变:
public static int foo(Object a){
int quantity = 0;
if(a != null && a.getInt() != null && a.getInt() != 5){ //modification here
quantity = a.getInt();
}
return quantity;
}
然后 testFoo 仍然必须通过。
但它没有,因为.times(2)
必须在.times(3)
.
所以这是我的问题:EasyMock 的 .times(x) 方法是单元测试稳健性的问题吗?如果不是,那么单元测试必须具备的最低稳健性水平是多少?
解决方案
首先,正如评论中提到的,您可能根本不需要通过模拟a
。也许使用一些真实的实例Object
很简单,并且不会对您的测试产生任何负面影响。
其次,如果您得出的结论是模拟是必要的,那么您可以times
通过为每个测试提供单独的模拟来避免使用。您只需要调用时间,因为您a_mock
在不同的测试之间重复使用。
更进一步,您甚至应该考虑将您的函数拆分testFoo
为三个不同的函数 - 或直接转换testFoo
为具有三个参数集的参数化测试。
推荐阅读
- php - 如果变量为空,如何避免换行?
- mysql - 如何获取具有不同字段的查询输出
- kubernetes - Kubernetes 中没有负载均衡器的 Nginx 入口控制器
- c# - 如何测试对象在特定状态下的状态?
- javascript - 如何在 Cast Receiver Player 中更新过期的 DRM 许可证?
- r - 数据集值替换未产生预期结果
- cordova - Cordova + ngrx/effect fire and forget long running 方法冻结 UI
- javascript - 如何在 Angular 中创建与反应形式一起使用的无线电组件?
- heroku - TypeError:无法读取未定义的属性“缩小”
- java - 如何创建具有不同配置的相同bean