美文网首页
mockito学习笔记

mockito学习笔记

作者: crossroads | 来源:发表于2017-12-21 10:56 被阅读235次

    前言

    根据中文版mockito英文版mockito的教程学习笔记。
    这里只有基础的一些,更深的目前没有用到,也就没写了,大家直接进链接看吧!

    一、验证某些行为

    一旦mock对象被创建了,mock对象会记住所有的交互。

        @Test
        @DisplayName("验证某些行为")
        void verifyBehavior() {
            //创建mockito对象
            List mockedList = mock(List.class);
            mockedList.add("one");
            mockedList.clear();
            //验证行为
            verify(mockedList).add("one");
            verify(mockedList).clear();
        }
    

    二、测试桩

     @Test
     void stubbing() {
            List mock = mock(ArrayList.class); //默认情况下,所有的函数都有返回值。mock函数默认返回的是null,一个空的集合或者一个被对象类型包装的内置类型,例如0、false对应的对象类型为Integer、Boolean
            System.out.println(mock + "--" + mock.size()); //输出Mock for ArrayList, hashCode: 480490520--0
            mock.add(0, "win");
            when(mock.get(0)).thenReturn("first"); //一旦测试桩函数被调用,该函数将会一致返回固定的值
            System.out.println(mock.get(0)); //输出first
            when(mock.get(0)).thenReturn("first change");
            when(mock.get(1)).thenReturn(new IndexOutOfBoundsException());
            System.out.println(mock.get(0)); //输出second
            System.out.println(mock.get(1)); //输出java.lang.IndexOutOfBoundsException
            //get(2) 没有打桩
            System.out.println(mock.get(2)); //输出null
     }
    

    三、参数匹配器

        @Test
        void argumentMatchers() {
            List mock = mock(ArrayList.class);
            when(mock.get(anyInt())).thenReturn("element");
            System.out.println(mock.get(10086));//输出element
        }
    

    四、验证函数的调用次数

        @Test
        void verifyExactNumber() {
            List mockedList = mock(List.class);
            mockedList.add("once");
            mockedList.add("twice");
            mockedList.add("twice");
            verify(mockedList, times(1)).add("once"); //执行了一次
            verify(mockedList, times(2)).add("twice");//执行了两次
            verify(mockedList, never()).add("never");
            verify(mockedList,atLeastOnce()).add("twice");
            verify(mockedList,atLeast(2)).add("twice");
            verify(mockedList,atMost(2)).add("twice");
        }
    

    五、抛出异常

        @Test
        void throwExceptions(){
            List mockedList = mock(List.class);
    //        doThrow(new RuntimeException()).when(mockedList).clear();
            doThrow(new RuntimeException()).when(mockedList).contains(anyInt());
    //        mockedList.clear(); //抛出java.lang.RuntimeException异常
            mockedList.contains(1); //抛出java.lang.RuntimeException异常
        }
    

    六、确保交互操作不会执行在mock对象上

        @Test
        void makeSureInteractionsNeverHappened(){
            List mockedList = mock(List.class);
            List mockedList2 = mock(List.class);
            mockedList.addAll(mockedList2);
            verifyZeroInteractions(mockedList,mockedList2);//抛出org.mockito.exceptions.verification.NoInteractionsWanted异常
        }
    

    七、验证执行顺序

     @Test
        void verificationInOrder(){
            List mockedList = mock(List.class);
            mockedList.add("first");
            mockedList.add("second");
            InOrder inOrder = inOrder(mockedList);
            inOrder.verify(mockedList).add("first");
            inOrder.verify(mockedList).add("second");
    
            List firstMockedList = mock(List.class);
            List secondMockedList = mock(List.class);
            firstMockedList.add("first");
            secondMockedList.add("first");
            InOrder multipleOrder = inOrder(firstMockedList, secondMockedList);
            multipleOrder.verify(firstMockedList).add("first");
            multipleOrder.verify(secondMockedList).add("first");
            verifyZeroInteractions(mockedList,firstMockedList,secondMockedList);
        }
    

    八、查找冗余的调用

    即验证传入的这些mock对象是否存在没有验证过的调用方法

        @Test
        void findRedundantInvocations() {
            List mockedList = mock(List.class);
            mockedList.add("one");
            verifyNoMoreInteractions(mockedList);//抛出org.mockito.exceptions.verification.NoInteractionsWanted异常
        }
    

    verifyNoMoreInteractions()在交互测试套件中只是一个便利的验证,它的作用是当你需要验证是否存在冗余调用时。滥用它将导致测试代码的可维护性降低,所以不建议过于频繁的在每个测试方法中都使用。

    九、简化mock对象的创建

        @Mock
        private ArrayList mockedList;
        @BeforeEach
        void setUp() {
            MockitoAnnotations.initMocks(this);
        }
        @Test
        void verifyBehavior() {
            mockedList.add("one");
            verify(mockedList).add("one");
        }
    

    十、为连续的调用做测试桩

        @Test
        void stubbingConsecutiveCalls(){
            when(mockedList.get(0)).thenReturn("first").thenReturn("second");
            //也可以这样写
            // when(mockedList.get(0)).thenReturn("first","second");
            System.out.println(mockedList.get(0)); //输出first
            System.out.println(mockedList.get(0)); //输出second
        }
    

    等价于

    doReturn("first","second").when(mockedList).get(0);
    System.out.println(mockedList.get(0)); //输出first
    System.out.println(mockedList.get(0)); //输出second
    

    这两种方式还是有区别的,我们在十一条中讲。

    十一、局部mocks(1.8.0+支持)

        @Test
        void realPartialMocks(){
            when(mockedList.get(10)).thenCallRealMethod(); //将会调用真实的方法
            System.out.println(mockedList.get(10));
        }
    
    

    在一些罕见的情况下部分测试才会是易用的:处理不能轻易修改的代码(第三方接口,临时重构的遗留代码等等)。然而,为了新的,测试驱动和架构优秀的代码,我是不会使用部分测试的。

    十二、重置mocks对象

            reset(mockedList);
    

    十三、小技巧~模板代码

    val eventLogicStub: EventLogic
        get() = mock(EventLogic::class.java).apply {
    
            doReturn(Observable.just(events))
                    .`when`(this)
                    .getEventsXX(anyString(), anyBoolean())
    
          doReturn(Single.just(events))
                    .`when`(this)
                    .getEventXX(anyString(), anyBoolean())
    
            doReturn(Single.just(files))
                    .`when`(this)
                    .getFilesXXX(anyString(), anyBoolean())
    
           doReturn(Maybe.just(files))
                    .`when`(this)
                    .getFileXX(anyString(), anyBoolean())
    ......
        }
    

    这样子一个个重复劳动该怎么省去呢?用代码模板,我的是这样的:
    输入dro,就可以得到如下的代码↓


    自定义快捷输入

    如何做?如何写?如下图


    模板代码

    如果你看到如下这样的提示,点击define,选择所在的组,例如我的是kotlin
    文件,就选择kotlin啦


    参考网址

    Android Studio 模板用法与自定义模板

    相关文章

      网友评论

          本文标题:mockito学习笔记

          本文链接:https://www.haomeiwen.com/subject/slfebxtx.html