当前位置:网站首页>Mockito 小结

Mockito 小结

2021-05-04 15:22:49 Kwanwooo

为什么要使用Mock进行测试

  1. 传统测试,后端工程师依赖一些第三方的接口(支付、定时任务等不方便真实测试的接口),前端工程师依赖后端的接口,测试工程师依赖前端的接口
  2. 使用Mock,使用虚拟对象进行测试,达到解耦、并行开发。

常见的mock框架

  • moco: 前端或测试利用moco生成接口文档
  • Mockito: 后端使用mockito进行单元测试

Mockito的常用API

  1. 添加Mockito依赖 和 Junit 依赖
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.8.0</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
  1. 生成 mock(模拟)对象 (多种方式)

若无特殊说明,所有的地方均静态导入了这个包

import static org.mockito.Mockito.*;

直接创建mock对象

//create mock
List mockedList = mock(List.class);

通过注解注入mock对象


@RunWith(MockitoJUnitRunner.class)
public class Test {

    @Mock
    private AService aService;

    @Test
    public void test() {
        //handle aService
    }
    interface AService {
        public boolean test();
    }

    @Service
    class AServiceImpl implements  AService {
        @Override
        public boolean test() {
            return false;
        }
    }

}

拓展,创建spy对象

        List mockList= mock(List.class);
        List spy = spy(mockList);
  1. 使用mock对象

测试桩(Stub)模式:默认情况,一个mock对象的函数返回为null或基础类型的默认值。测试桩函数会覆盖函数返回值。

一个简单的例子

        // 创建 mock 对象
        List mockedList = mock(List.class);

        // 测试桩
        when(mockedList.get(0)).thenReturn("first");
        // 连续测试桩
        when(mockedList.get(1)).thenReturn("once").thenReturn("twice");
        // 异常测试桩
        when(mockedList.get(2)).thenThrow(new RuntimeException());

        // 打印 first
        System.out.println(mockedList.get(0));
        // 打印 once
        System.out.println(mockedList.get(1));
        // 打印 twice
        System.out.println(mockedList.get(1));
        // 打印 null
        System.out.println(mockedList.get(999));
        // 报 RuntimeException 异常
        System.out.println(mockedList.get(2));

使用 anyXXX()

        // 创建 mock 对象
        List mockedList = mock(List.class);

        when(mockedList.get(anyInt())).thenReturn("element");
        //打印 element
        System.out.println(mockedList.get(999));
        verify(mockedList).get(anyInt());

次数验证

        // 创建 mock 对象
        List mockedList = mock(List.class);

        mockedList.add("once");
        mockedList.add("twice");
        mockedList.add("twice");
        mockedList.add("three times");
        mockedList.add("three times");
        mockedList.add("three times");

        // 1次 once
        verify(mockedList, times(1)).add("once");
        // 2次 twice
        verify(mockedList, times(2)).add("twice");
        // 3次 three times
        verify(mockedList, times(3)).add("three times");
        // 一次都不存在 never happened
        verify(mockedList, never()).add("never happened");

        // 拓展
        // 最少一次 three times
        verify(mockedList, atLeastOnce()).add("three times");
        // 最少两次 five times
//        verify(mockedList, atLeast(2)).add("five times");
        // 最多5次 three times
//        verify(mockedList, atMost(5)).add("three times");

顺序验证

        // 创建 mock 对象, 进行单个对象的顺序验证
        List singleMock = mock(List.class);

        singleMock.add("was added first");
        singleMock.add("was added second");

        InOrder inOrder = inOrder(singleMock);

        inOrder.verify(singleMock).add("was added first");
        inOrder.verify(singleMock).add("was added second");

        // 创建多个 mock 对象,进行多个mock对象的顺序验证
        List firstList = mock(List.class);
        List secondList = mock(List.class);

        firstList.add("was added first");
        secondList.add("was added second");

        InOrder order = inOrder(firstList, secondList);
        order.verify(firstList).add("was added first");
        order.verify(secondList).add("was added second");

参考文档

版权声明
本文为[Kwanwooo]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/kwanwoo/p/14729495.html

随机推荐