zoukankan      html  css  js  c++  java
  • 【mockito】单元测试之mockito简单使用

    背景

    项目使用的是springmvc+mybatis 开发;

    mock包为 mockito-all;虽然也引用了powermock,但截至目前,还未使用到;如果使用到后续再补相关笔记。

    mock,个人理解,有两个场景比较常见吧。一个是在项目初期接口定义好后没有实现逻辑阶段;另一个就是针对已经有的逻辑自测阶段,而又不想(或者依赖的别人接口不想关心)被别人所左右的情况。

    不管那种情况,都是一个目的:降低别人对自己的干扰。

    大概从两个方面记录单测的mock:

    dapper层:

      dapper层,目前是给mybatis的定义接口层;这一层主要会结合mybatis.xml 与数据库进行交互;当开发阶段没有写完逻辑时,那就需要先来个“假实现”,这样不会影响团队中其他小伙伴的工作开展嘛。

    public class ReportMediaDayMapperTest {
    
        @Mock
        private ReportMediaDayMapper reportMediaDayMapper; // 定义了mybatis与数据库交互时,用到的接口
    
        @Before
        public void setUp() throws Exception {
            MockitoAnnotations.initMocks(this);
        }
    
        @After
        public void tearDown() throws Exception {
    
        }
    
        @Test
        public void getAdvertiserAndMediaStatList() throws Exception {
            MediaSearchModel searchModel = new MediaSearchModel();
            List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
            when(reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list); // mock一个场景,就是当请求getAdvertiserAndMediaStatList方法时,返回值为指定的 list;
        List<AdvertiserAndMediaStatViewModel> list2 = reportMediaDayMapper.getAdvertiserAndMediaStatList(searchModel); 
        assertTrue(list2.isEmpty()); // 断言list2为空,因为上面就是一个实例化并没有赋值,所以也是为空了。
    }

    对于DAO层,主要用到的是 @Mock的使用。那么这个注解的作用究竟是什么呢?下面会结合另外一个一起总结。

    service层:

      主要mock对象一般就是对DAO层的依赖,另外就是别人的Service实现类;

    @RunWith(MockitoJUnitRunner.class)
    public class MediaServiceImplTest {
    
        @Mock
        private ReportMediaDayMapper mediaDayMapper; // mock 一个DAO层的接口
    
        @InjectMocks
        private MediaServiceImpl mediaService; // Mock一个Service的实现类,为什么用@InjectMocks,一会儿说
    
        @Test
        public void getAdvertiserAndMediaStatList() throws Exception {
            MediaSearchModel searchModel = new MediaSearchModel();
            List<AdvertiserAndMediaStatViewModel> list = new ArrayList<>();
            when(mediaDayMapper.getAdvertiserAndMediaStatList(searchModel)).thenReturn(list);
    
            list = mediaService.getAdvertiserAndMediaStatList(searchModel);
    
            assertTrue(list.isEmpty());
        }

    其实,对于以上两个场景的mock,主要是围绕着@Mock、@InjectMocks进行玩的。那么他们分别代表什么意思呢?

    官方文档上是这么描述的:

    • mock()/@Mock: create mockspy()/@Spy: partial mocking, real methods are invoked but still can be verified and stubbed
    • @InjectMocks: automatically inject mocks/spies fields annotated with @Spy or @Mock -- 这句话理解意思是它会把上下文中你标记为@Spy和@Mock的对象都自动注解进去。是不是就相当于把实现类中的私有成员属性(比如ReportMediaDayMapper的依赖)给偷梁换柱了
    • verify(): to check methods were called with given arguments
      • can use flexible argument matching, for example any expression via the any()
      • or capture what arguments where called using @Captor instead

    另外,就是你可能会注意到了@RunWith(MockitoJUnitRunner.class),其实也可以用另外一种方式(看↓)处理,就是初始化一些需要的东西。

    @Before
        public void setUp() throws Exception {
            MockitoAnnotations.initMocks(this); 
        }
    
        @After
        public void tearDown() throws Exception {
    
        }

    至此,简单的mock测试就完了。其实只是冰山一角。mockito中有很多很多很多。常用的一些@spy、@mock、@injectMocks、以及Verify、when then、doreturn ……

    参考:

    https://github.com/hehonghui/mockito-doc-zh

    http://site.mockito.org/

    http://static.javadoc.io/org.mockito/mockito-core/2.7.6/org/mockito/Mockito.html

  • 相关阅读:
    汇编指令:ldr和str,ldm和stm的区别
    面向对象(成员(变量,方法,属性)组合并嵌套)
    面向对象三大特性编写面向对象程序,self到底是谁
    内置函数二. 递归 二分法
    内置函数
    生成器;三元表达式, 推导式
    函数名的应用,闭包,迭代器
    函数的进阶
    闭包,迭代器
    函数
  • 原文地址:https://www.cnblogs.com/hager/p/6401916.html
Copyright © 2011-2022 走看看