最近公司对测试用例要求很严格,以前对这一块了解不多。趁此机会学习一下!
写代码,一般免不了写单元测试。如果是单系统,没有依赖,直接写Junit测试即可。但是稍微复杂一些的系统,都会涉及到系统交互,尤其是接口的调用。通常大型的系统,都是分工协作,比如A系统你复杂,B系统可能是另外的人复杂,这个时候如果你要写测试,就有可能依赖于上下游的服务。
考虑一种情况,你开发好了,B开发未完成或者是B服务的环境没有,那怎么办呢?如果B还有对应的依赖呢?
这个时候,一种方式是,把对应的依赖树都构建起来,即BDE都准备好
还有一种方式,对依赖进行mocks,使用例通过
至此,尝试给出一个mock的解释:
mock对象就是在测试过程中,替代真实的调用对象
mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试
Mock的框架不少,使用了一下,觉得Mockito上手还比较快,也挺好用。就来看看demo,有个体感
添加Maven依赖,首先添加mockito,由于需要Junit配合,所以pom添加
org.mockito
mockito-all
1.10.19
test
junit
junit
4.11
test
1.验证行为
@Test
public void verifyBehaviour() {
// 模拟创建一个List对象
List mock = mock(List.class);
// 使用mock对象
mock.add(1);
mock.clear();
// 验证add(1)和clear()行为是否发生
Mockito.verify(mock).add(1);
Mockito.verify(mock).clear();
}
2.模拟我们所期望的结果
@Test
public void whenThenReturn() {
// mock一个iterator
Iterator iterator = mock(Iterator.class);
// 预设当iterator调用next()时第一次返回hello,第n次都返回world
when(iterator.next()).thenReturn("hello").thenReturn("world");
// 使用mock对象
String result = iterator.next() + " " + iterator.next() + " " + iterator.next();
Assert.assertEquals("hello world world", result);
}
3.模拟异常
@Test(expected = IOException.class)
public void whenThenThrow() throws IOException {
// mock一个对象
OutputStream outputStream = mock(OutputStream.class);
// 预设当流关闭时抛出异常
doThrow(new IOException()).when(outputStream).close();
outputStream.close();
}
4.参数匹配
@Test
public void withArguments() {
Comparable comparable = mock(Comparable.class);
// 预设根据不同的参数返回不同的结果
when(comparable.compareTo("Test")).thenReturn(1);
when(comparable.compareTo("Omg")).thenReturn(2);
Assert.assertEquals(1, comparable.compareTo("Test"));
Assert.assertEquals(2, comparable.compareTo("Omg"));
// 对于没有预设的情况会返回默认值
Assert.assertEquals(0, comparable.compareTo("Not Stub"));
}
5.验证确切的调用次数
@Test
public void verifyingNumberOfInvocations() {
List list = mock(List.class);
list.add(1);
list.add(2);
list.add(2);
list.add(3);
list.add(3);
list.add(3);
// 验证是否被调用一次,等效于下面的times(1)
verify(list).add(1);
verify(list, times(1)).add(1);
// 验证是否被调用2次
verify(list, times(2)).add(2);
// 验证是否被调用2次
verify(list, times(3)).add(3);
//验证是否从未被调用过
verify(list, never()).add(4);
//验证至少调用一次
verify(list, atLeastOnce()).add(1);
//验证至少调用2次
verify(list, atLeast(2)).add(2);
//验证至多调用3次
verify(list, atMost(3)).add(3);
}
6、验证执行顺序
public class MockitoTest {
@Test
public void test1() {
TestA a = Mockito.mock(TestA.class);
TestA b = Mockito.mock(TestA.class);
a.method1();
b.method2();
InOrder inOrder = Mockito.inOrder(a, b);
inOrder.verify(a).method1();
inOrder.verify(b).method2();
}
class TestA {
public void method1() {
}
public void method2() {
}
}
}
7、确保模拟对象上无互动发生
@Test
public void test2() {
TestA a = Mockito.mock(TestA.class);
// 方法未被执行过
Mockito.verify(a, Mockito.never()).method1();
}
5分钟了解Mockito:https://liuzhijun.iteye.com/blog/1512780