Mockito

最近公司对测试用例要求很严格,以前对这一块了解不多。趁此机会学习一下!

什么是mock

写代码,一般免不了写单元测试。如果是单系统,没有依赖,直接写Junit测试即可。但是稍微复杂一些的系统,都会涉及到系统交互,尤其是接口的调用。通常大型的系统,都是分工协作,比如A系统你复杂,B系统可能是另外的人复杂,这个时候如果你要写测试,就有可能依赖于上下游的服务。

考虑一种情况,你开发好了,B开发未完成或者是B服务的环境没有,那怎么办呢?如果B还有对应的依赖呢?

Mockito_第1张图片

 这个时候,一种方式是,把对应的依赖树都构建起来,即BDE都准备好

还有一种方式,对依赖进行mocks,使用例通过

Mockito_第2张图片

至此,尝试给出一个mock的解释:

mock对象就是在测试过程中,替代真实的调用对象

mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试

Mock框架

Mock的框架不少,使用了一下,觉得Mockito上手还比较快,也挺好用。就来看看demo,有个体感

添加Maven依赖,首先添加mockito,由于需要Junit配合,所以pom添加


                org.mockito
                mockito-all
                1.10.19
                test
            


        junit
        junit
        4.11
        test
      

下面开始用mockito验证行为

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

你可能感兴趣的:(JAVA,不得不学)