使用 Easymock 进行案例测试
Test with Easymock for cases testing
我目前正在进行单元测试,我正在尝试创建一个测试来测试单个函数的不同情况。例如,我有以下功能:
public static String foo(Object arg0, Object arg1) {
String returnValue = null;
if(arg0.getName() != null && arg0.getId() != null) {
returnValue = "Value 1";
} else if (arg1.getName() != null && arg1.getId() != null ) {
returnValue = "Value 2";
}
return returnValue;
}
我想测试以下情况:
- 案例 1:
arg0.getName() == null
和 arg1.getName() == null
- 案例 2:
arg0.getName() != null
和 arg0.getId() != null
和 arg1.getName() == null
- 案例 3:
arg0.getName() == null
和 arg1.getName() != null
和 arg1.getId() != null
等...
我目前的测试是这样的:
public void testFoo() {
/** Setting up my mocks**/
Obj arg0 = createMock(Obj.class);
Obj arg1 = createMock(Obj.class);
/** Setting my mocks behaviors **/
// Case 1
EasyMock.expect(arg0.getName()).andReturn(null);
EasyMock.expect(arg1.getName()).andReturn(null);
// Case 2
EasyMock.expect(arg0.getName()).andReturn("Jack");
EasyMock.expect(arg0.getId()).andReturn(1);
EasyMock.expect(arg1.getName()).andReturn(null);
// Case 3
EasyMock.expect(arg0.getName()).andReturn(null);
EasyMock.expect(arg1.getName()).andReturn("Paul");
EasyMock.expect(arg1.getId()).andReturn(2);
//End Cases
EasyMock.replay(arg0_case1, arg0_case2, arg0_case3,
arg1_case1, arg1_case2, arg1_case3);
/** Testing **/
// Case 1
String expectedValue = null;
String output = foo(arg0, arg1);
assertEquals(expectedValue, output);
// Case 2
expectedValue = "Value 1";
output = foo(arg0, arg1);
assertEquals(expectedValue, output);
// Case 3
expectedValue = "Value 2";
output = foo(arg0, arg1);
assertEquals(expectedValue, output);
}
我在这个测试中遇到的问题是,即使我为每个测试用例设置了模拟,设置似乎也没有按照我选择的顺序进行。我尝试添加 .once()
、atLeastOnce()
,但即使这样,它还是失败了。
对于这种测试你有什么解决办法吗?也许我应该为每种情况编写不同的测试?
编辑
感谢@swayamraina 的解决方案和对我的代码的一些修改,我找到了解决方案。这不是最有效的答案,但可以完成工作。这是我编辑的代码:
public void testFoo() {
/** Setting my mocks behaviors **/
// Case 1
Obj arg0_case1 = createMock(Obj.class);
Obj arg1_case1 = createMock(Obj.class);
EasyMock.expect(arg0_case1.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case1.getName()).andReturn(null).anyTimes();
// Case 2
Obj arg0_case2 = createMock(Obj.class);
Obj arg1_case2 = createMock(Obj.class);
EasyMock.expect(arg0_case2.getName()).andReturn("Jack").anyTimes();
EasyMock.expect(arg0_case2.getId()).andReturn(1).anyTimes();
EasyMock.expect(arg1_case2.getName()).andReturn(null).anyTimes();
// Case 3
Obj arg0_case3 = createMock(Obj.class);
Obj arg1_case3 = createMock(Obj.class);
EasyMock.expect(arg0_case3.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case3.getName()).andReturn("Paul").anyTimes();
EasyMock.expect(arg1_case3.getId()).andReturn(2).anyTimes();
//End Cases
EasyMock.replay(arg0, arg1);
/** Testing **/
// Case 1
String expectedValue = null;
String output = foo(arg0_case1, arg1_case1);
assertEquals(expectedValue, output);
// Case 2
expectedValue = "Value 1";
output = foo(arg0_case2, arg1_case2);
assertEquals(expectedValue, output);
// Case 3
expectedValue = "Value 2";
output = foo(arg0_case3, arg1_case3);
assertEquals(expectedValue, output);
就像@swayamraina 在其回答中提出的那样,我为每个案例测试创建了不同的模拟,并在每个 EasyMock.expect().andReturn()
之后添加了一个 .anyTimes()
,并且效果很好。
我会保留此 post 关于我可能实施的改进的更新。
下面是更新后的测试用例
@Test
public void test() {
A arg0, arg1;
// Case 1
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn(null).once();
EasyMock.expect(arg1.getName()).andReturn(null).once();
EasyMock.replay(arg0, arg1);
// actuals
String expectedValue = null;
String output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
// Case 2
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn("Jack").once();
EasyMock.expect(arg0.getId()).andReturn(1).once();
EasyMock.expect(arg1.getName()).andReturn(null).once();
EasyMock.replay(arg0, arg1);
// actuals
expectedValue = "Value 1";
output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
// Case 3
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn(null).once();
EasyMock.expect(arg1.getName()).andReturn("Paul").once();
EasyMock.expect(arg1.getId()).andReturn(2).once();
EasyMock.replay(arg0, arg1);
// actuals
expectedValue = "Value 2";
output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
}
使用的测试class:
class A {
String name; public String getName() {return name;}
Integer id; public Integer getId(){return id;}
}
备注:
您只能重播模拟一次。您需要为每个测试用例创建新的测试对象。在这里,我们首先创建模拟,然后设定期望并重播模拟。最后断言实际值。
作为一般流程,我喜欢使用 .多个测试用例描述每个。
每个测试用例也遵循以下模式
- 声明变量
- 描述测试用例
- 设定期望
- 定义结果(实际)
- 应用断言
我目前正在进行单元测试,我正在尝试创建一个测试来测试单个函数的不同情况。例如,我有以下功能:
public static String foo(Object arg0, Object arg1) {
String returnValue = null;
if(arg0.getName() != null && arg0.getId() != null) {
returnValue = "Value 1";
} else if (arg1.getName() != null && arg1.getId() != null ) {
returnValue = "Value 2";
}
return returnValue;
}
我想测试以下情况:
- 案例 1:
arg0.getName() == null
和arg1.getName() == null
- 案例 2:
arg0.getName() != null
和arg0.getId() != null
和arg1.getName() == null
- 案例 3:
arg0.getName() == null
和arg1.getName() != null
和arg1.getId() != null
等...
我目前的测试是这样的:
public void testFoo() {
/** Setting up my mocks**/
Obj arg0 = createMock(Obj.class);
Obj arg1 = createMock(Obj.class);
/** Setting my mocks behaviors **/
// Case 1
EasyMock.expect(arg0.getName()).andReturn(null);
EasyMock.expect(arg1.getName()).andReturn(null);
// Case 2
EasyMock.expect(arg0.getName()).andReturn("Jack");
EasyMock.expect(arg0.getId()).andReturn(1);
EasyMock.expect(arg1.getName()).andReturn(null);
// Case 3
EasyMock.expect(arg0.getName()).andReturn(null);
EasyMock.expect(arg1.getName()).andReturn("Paul");
EasyMock.expect(arg1.getId()).andReturn(2);
//End Cases
EasyMock.replay(arg0_case1, arg0_case2, arg0_case3,
arg1_case1, arg1_case2, arg1_case3);
/** Testing **/
// Case 1
String expectedValue = null;
String output = foo(arg0, arg1);
assertEquals(expectedValue, output);
// Case 2
expectedValue = "Value 1";
output = foo(arg0, arg1);
assertEquals(expectedValue, output);
// Case 3
expectedValue = "Value 2";
output = foo(arg0, arg1);
assertEquals(expectedValue, output);
}
我在这个测试中遇到的问题是,即使我为每个测试用例设置了模拟,设置似乎也没有按照我选择的顺序进行。我尝试添加 .once()
、atLeastOnce()
,但即使这样,它还是失败了。
对于这种测试你有什么解决办法吗?也许我应该为每种情况编写不同的测试?
编辑 感谢@swayamraina 的解决方案和对我的代码的一些修改,我找到了解决方案。这不是最有效的答案,但可以完成工作。这是我编辑的代码:
public void testFoo() {
/** Setting my mocks behaviors **/
// Case 1
Obj arg0_case1 = createMock(Obj.class);
Obj arg1_case1 = createMock(Obj.class);
EasyMock.expect(arg0_case1.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case1.getName()).andReturn(null).anyTimes();
// Case 2
Obj arg0_case2 = createMock(Obj.class);
Obj arg1_case2 = createMock(Obj.class);
EasyMock.expect(arg0_case2.getName()).andReturn("Jack").anyTimes();
EasyMock.expect(arg0_case2.getId()).andReturn(1).anyTimes();
EasyMock.expect(arg1_case2.getName()).andReturn(null).anyTimes();
// Case 3
Obj arg0_case3 = createMock(Obj.class);
Obj arg1_case3 = createMock(Obj.class);
EasyMock.expect(arg0_case3.getName()).andReturn(null).anyTimes();
EasyMock.expect(arg1_case3.getName()).andReturn("Paul").anyTimes();
EasyMock.expect(arg1_case3.getId()).andReturn(2).anyTimes();
//End Cases
EasyMock.replay(arg0, arg1);
/** Testing **/
// Case 1
String expectedValue = null;
String output = foo(arg0_case1, arg1_case1);
assertEquals(expectedValue, output);
// Case 2
expectedValue = "Value 1";
output = foo(arg0_case2, arg1_case2);
assertEquals(expectedValue, output);
// Case 3
expectedValue = "Value 2";
output = foo(arg0_case3, arg1_case3);
assertEquals(expectedValue, output);
就像@swayamraina 在其回答中提出的那样,我为每个案例测试创建了不同的模拟,并在每个 EasyMock.expect().andReturn()
之后添加了一个 .anyTimes()
,并且效果很好。
我会保留此 post 关于我可能实施的改进的更新。
下面是更新后的测试用例
@Test
public void test() {
A arg0, arg1;
// Case 1
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn(null).once();
EasyMock.expect(arg1.getName()).andReturn(null).once();
EasyMock.replay(arg0, arg1);
// actuals
String expectedValue = null;
String output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
// Case 2
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn("Jack").once();
EasyMock.expect(arg0.getId()).andReturn(1).once();
EasyMock.expect(arg1.getName()).andReturn(null).once();
EasyMock.replay(arg0, arg1);
// actuals
expectedValue = "Value 1";
output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
// Case 3
arg0 = EasyMock.createMock(A.class);
arg1 = EasyMock.createMock(A.class);
// expectations
EasyMock.expect(arg0.getName()).andReturn(null).once();
EasyMock.expect(arg1.getName()).andReturn("Paul").once();
EasyMock.expect(arg1.getId()).andReturn(2).once();
EasyMock.replay(arg0, arg1);
// actuals
expectedValue = "Value 2";
output = foo(arg0, arg1);
// assertions
Assert.assertEquals(expectedValue, output);
}
使用的测试class:
class A {
String name; public String getName() {return name;}
Integer id; public Integer getId(){return id;}
}
备注:
您只能重播模拟一次。您需要为每个测试用例创建新的测试对象。在这里,我们首先创建模拟,然后设定期望并重播模拟。最后断言实际值。
作为一般流程,我喜欢使用 .多个测试用例描述每个。
每个测试用例也遵循以下模式
- 声明变量
- 描述测试用例
- 设定期望
- 定义结果(实际)
- 应用断言