mockito学习资料:

http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html

http://blog.csdn.net/sdyy321/article/details/38757135

1、验证行为是否发生

1
2
3
4
5
6
7
8
@Test
public void mockedList(){
    List mockedList = mock(List.class);
    mockedList.add("one");
    mockedList.clear();
    verify(mockedList).add("one");
    verify(mockedList).clear();
}

验证add和clear是否执行。

2、验证返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
    public void two(){
        //模拟创建一个List对象
        LinkedList mockLinkedList = mock(LinkedList.class);
 
        //打桩,当LinkedList调用get(0)方法时,第一次返回zero,第二次n次返回nnnn
        when(mockLinkedList.get(0)).thenReturn("zero").thenReturn("nnnn");
 
        //使用mock对象
        System.out.println(mockLinkedList.get(0));
        System.out.println(mockLinkedList.get(0));
        System.out.println(mockLinkedList.get(0));
 
        //验证行为get是否发生
        verify(mockLinkedList).get(0);
 
    }

这里注意所有的方法都会有返回值,如果没有设置返回值,那么就会返回null或者空集、适当的类型。 Stubbing可以被重写,也就是同一个参数方法可以放回不同的值,但是已最后一次设置的值为标准。一旦被 Stubbed,无论方法被调用多少次,都只会返回Stubbed value。最后一次最重要原则。

3、参数匹配

通过equals()来验证参数。

不同的参数返回不同的结果:

1
2
when(comparable.compareTo("Test")).thenReturn(1); 
when(comparable.compareTo("Omg")).thenReturn(2);

一旦你使用了参数匹配器,那么所有的参数都必须由匹配器给出:

1
2
3
4
5
6
7
8
9
10
11
//stubbing using built-in anyInt() argument matcher
 when(mockedList.get(anyInt())).thenReturn("element");
 
 //stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher):
 when(mockedList.contains(argThat(isValid()))).thenReturn("element");
 
 //following prints "element"
 System.out.println(mockedList.get(999));
 
 //you can also verify using an argument matcher
 verify(mockedList).get(anyInt());
1
2
3
4
5
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
   //above is correct - eq() is also an argument matcher
 
   verify(mock).someMethod(anyInt(), anyString(), "third argument");
   //above is incorrect - exception will be thrown because third argument is given without an argument matcher.

4、验证调用次数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Test
    public void three(){
        List mockedList = mock(List.class);
        mockedList.add(1);
        mockedList.add(2);
        mockedList.add(2);
        mockedList.add(3);
        mockedList.add(3);
        mockedList.add(3);
        //验证是否被调用一次,等效于下面的times(1),默认的,可以不写
        verify(mockedList).add(1);
        verify(mockedList,times(1)).add(1);
        //验证是否被调用2次 
        verify(mockedList,times(2)).add(2);
        //验证是否被调用3次 
        verify(mockedList,times(3)).add(3);
        //验证是否从未被调用过
        verify(mockedList,never()).add(4);
        //验证至少调用一次
        verify(mockedList,atLeastOnce()).add(1);
        //验证至少调用2次
        verify(mockedList,atLeast(2)).add(2);
        //验证至多调用3次
        verify(mockedList,atMost(3)).add(3);
    }

add(1)这个方法被调用了1次,add(2)这个被调用了2次。add(3)这个方法被调用了3次,如果将verify(mockedList,times(1)).add(3);运行后那么就会出现错误:

5、模拟方法体抛出异常

1
2
3
4
5
6
doThrow(new RuntimeException()).when(mockedList).clear(); 
  //following throws RuntimeException:
mockedList.clear();
 
doThrow(new RuntimeException()).when(list).add(1); 
list.add(1);

6、验证执行的顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
    public void four(){
        List firstList = mock(List.class);
        List secondList = mock(List.class);
        //using mocks
        firstList.add("was called first one mock");
        secondList.add("was called second one mock");
        //create inOrder object passing any mocks that need to be verified in order
        InOrder indOrder = inOrder(firstList,secondList);
 
        indOrder.verify(firstList).add("was called first one mock");
        indOrder.verify(secondList).add("was called second one mock");
 
 
    }

如果将11,12调换,

indOrder.verify(secondList).add("was called second one mock");

indOrder.verify(firstList).add("was called first one mock");

会出现如下错误:

可是如果顺序如下:

1
2
3
4
5
firstList.add("was called first one mock");
secondList.add("was called second one mock");
InOrder indOrder = inOrder(secondList,firstList);
indOrder.verify(firstList).add("was called first one mock");
indOrder.verify(secondList).add("was called second one mock");

inorder中顺序调换后,上面程序居然没有出错?难道我理解错了。验证的顺序是按照inOrder中给出的,也就是second要在first前面,而在verify中明显second在first后验证了,应该出错啊。

7、模拟对象上没有相互关系

1
2
3
4
5
6
7
8
9
10
11
//using mocks - only mockOne is interacted
 mockOne.add("one");
 
 //ordinary verification
 verify(mockOne).add("one");
 
 //verify that method was never called on a mock
 verify(mockOne, never()).add("two");
 
 //verify that other mocks were not interacted
 verifyZeroInteractions(mockTwo, mockThree);

8、找出多余的调用

1
2
3
4
5
6
7
8
9
10
11
12
//using mocks
 mockedList.add("one");
 mockedList.add("two");
 
 verify(mockedList).add("one");
 
 //following verification will fail 检查是否有未被验证的行为
 verifyNoMoreInteractions(mockedList);
 
  verify(list,times(2)).add(anyInt()); 
//检查是否有未被验证的互动行为,因为add(1)和add(2)都会被上面的anyInt()验证到,所以下面的代码会通过 
   verifyNoMoreInteractions(list);

mockedList还有add("two")没有验证,所以出错。

9、使用注解来mock

这里注意要在构造函数中初试化mock对象,否则mock对象为null。

也可以通过在类上使用注解:@RunWith(MockitoJUnitRunner.class)

这样就不需要初始化mock了。

10、连续调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test(expected = RuntimeException.class
    public void consecutive_calls(){ 
        List mockList = mock(List.class);
        //模拟连续调用返回期望值,如果分开,则只有最后一个有效 
        when(mockList.get(0)).thenReturn(0); 
        when(mockList.get(0)).thenReturn(1); 
        when(mockList.get(0)).thenReturn(2); 
        when(mockList.get(1)).thenReturn(0).thenReturn(1).thenThrow(new RuntimeException()); 
        assertEquals(2,mockList.get(0)); 
        assertEquals(2,mockList.get(0)); 
        assertEquals(0,mockList.get(1)); 
        assertEquals(1,mockList.get(1)); 
        //第三次或更多调用都会抛出异常 
        mockList.get(1); 
    }

11、使用回调来stub

通用:

1
2
3
4
5
6
7
8
9
10
when(mock.someMethod(anyString())).thenAnswer(new Answer() {
     Object answer(InvocationOnMock invocation) {
         Object[] args = invocation.getArguments();
         Object mock = invocation.getMock();
         return "called with arguments: " + args;
     }
 });
  
 //Following prints "called with arguments: foo"
 System.out.println(mock.someMethod("foo"));

使用:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
    public void six(){
        List mockList = mock(List.class);
        when(mockList.get(anyInt())).thenAnswer(new Answer<Object>() {
            public Object answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                return "hi:"+args[0];
            }
        });
        assertEquals("hi:0",mockList.get(0));
        assertEquals("hi:1",mockList.get(1));
    }

12、对于void方法,有系列函数可以用来处理。

doThrow() doAnswer doNothing doReturn。当一个void的方法有异常抛出时可以使用doThrow()。

13、监控真实对象

当使用spy的时候真正的方法将会被调用,而不再是stub的对象了,这个和部分mock的思想是一样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
    public void seven(){
        List list = new LinkedList();
        List spy = spy(list);
          
        //optionally, you can stub out some methods:
        when(spy.size()).thenReturn(100);
          
        //using the spy calls real methods
        spy.add("one");
        spy.add("two");
          
        //prints "one" - the first element of a list
        System.out.println(spy.get(0));
          
        //size() method was stubbed - 100 is printed
         System.out.println(spy.size());
          
        //optionally, you can verify
        verify(spy).add("one");
        verify(spy).add("two");
    }

使用spy的时候需要注意一点:有时候是不能使用when语句的

1
2
3
4
5
6
7
8
List list = new LinkedList();
   List spy = spy(list);
    
   //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
   when(spy.get(0)).thenReturn("foo");
    
   //You have to use doReturn() for stubbing
   doReturn("foo").when(spy).get(0);

14、设置未stub的调用的默认值

对于没有stub方法的调用,我们一般返回null,或者是默认类型。也可以修改使其返回你指定的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test 
    public void eight(){ 
        //mock对象使用Answer来对未预设的调用返回默认期望值 
        List mocklist = mock(List.class,new Answer(){ 
            public Object answer(InvocationOnMock invocation) throws Throwable { 
                return 999
            }
        }); 
        //下面的get(1)没有预设,通常情况下会返回NULL,但是使用了Answer改变了默认期望值 
        assertEquals(999, mocklist.get(1)); 
        //下面的size()没有预设,通常情况下会返回0,但是使用了Answer改变了默认期望值 
        assertEquals(999,mocklist.size()); 
    }

 

mockito使用的更多相关文章

  1. Junit mockito 测试Controller层方法有Pageable异常

    1.问题 在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的 ...

  2. Junit mockito解耦合测试

    Mock测试是单元测试的重要方法之一. 1.相关网址 官网:http://mockito.org/ 项目源码:https://github.com/mockito/mockito api:http:/ ...

  3. Android 单元测试(junit、mockito、robolectric)

    1.运用JUnit4 进行单元测试 首先在工程的 src 文件夹内创建 test 和 test/java 文件夹. 打开工程的 build.gradle(Module:app)文件,添加JUnit4依 ...

  4. Mockito Hello World

    Mockito Hello World 项目配置 IDE是Intellij IDEA,用gradle配置项目. 新建一个Java项目,gradle中需要有这个:   repositories { jc ...

  5. mockito使用心得

    前提:pom引用<dependency> <groupId>junit</groupId> <artifactId>junit</artifact ...

  6. Mock之easymock, powermock, and mockito

    easymock, powermock, and mockito Easymock Class Mocking Limitations To be coherent with interface mo ...

  7. 用Mockito mock普通的方法

    上面的例子是很理想化的状态,但是在实际的开发中,我们需要经常调用一些依赖特定环境的函数或者调用同事写的代码,而同事仅提供了接口.这个时候就需要利用Mockito来协助我们完成测试. 当然,你可以选择e ...

  8. mock测试框架Mockito

    无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...

  9. Mockito自定义verify参数Matcher

    在TDD开发中,也许我们会遇见对一些重要的无返回值的行为测试,比如在用户的积分DB中增加用户的积分,这个行为对于我们的业务具有重要的价值,所以我们也希望能测试覆盖这部分业务价值.这个时候我们就得使用m ...

  10. Mockito学习资料

    官网:http://mockito.org/ https://dzone.com/refcardz/mockito

随机推荐

  1. 补充2:Golang 一些特性

    Go语言的这些地方都做的还不错: 拥有自动垃圾回收: 不用手动释放内存 一个包系统: Go 语言的源码复用建立在包(package)基础之上.包通过 package, import, GOPATH 操 ...

  2. Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本)

    Hive环境的安装部署(完美安装)(集群内或集群外都适用)(含卸载自带mysql安装指定版本) Hive 安装依赖 Hadoop 的集群,它是运行在 Hadoop 的基础上. 所以在安装 Hive 之 ...

  3. Hadoop使用场景

    Hadoop使用场景: 大数据量存储:分布式存储 日志处理: Hadoop擅长这个 海量计算: 并行计算 ETL:数据抽取到oracle.mysql.DB2.mongdb及主流数据库 使用HBase做 ...

  4. 今天练手了下mysqlbinlog,标记下

    1 首先查看是否开启了 bin log 登录mysql后  使用命令 show variables like "log_%"; show binary logs; 2  确认开启了 ...

  5. 15. "wm_concat"_数据库中将查询出来的多条记录中的某个字段用","拼接起来

    例子: select wm_concat(roleid) from lbmember where userid = ? 值的形式:1,2,3 下面是把1,2,3转换为1;2;3select repla ...

  6. Security4.1.3实现根据请求跳转不同登录页以及登录后根据权限跳转到不同页配置

    参考博客:https://blog.csdn.net/honghailiang888/article/details/53765508

  7. leetcode179

    class Solution { public: string largestNumber(vector<int>& nums) { int n=nums.size(); vect ...

  8. javarscript在HTML中的调用方式 (直接调用 和文件调用)

    //文件调用<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  9. tensorflow笔记之滑动平均模型

    tensorflow使用tf.train.ExponentialMovingAverage实现滑动平均模型,在使用随机梯度下降方法训练神经网络时候,使用这个模型可以增强模型的鲁棒性(robust),可 ...

  10. Kotlin语言学习笔记(6)

    运算符重载(Operator overloading) 一元运算符 Expression Translated to +a a.unaryPlus() -a a.unaryMinus() !a a.n ...