Mockito快速使用教程

1. 什么是 Mockito

Mockito 是一个强大的用于 Java 开发的模拟测试框架, 通过 Mockito 我们可以创建和配置 Mock 对象, 进而简化有外部依赖的类的测试.

 

2. 为什么使用Mockito

我们系统一般的功能是controller->biz->service→Dao

如果我们只想测试一个biz中的功能,我们必须配置好类与类之间的关系,组装好一个完整的biz对象,才能去运行biz中要测试的代码,但是在微服务大行其道的今天,有些依赖是本地无法运行的,或者你本地是连接不到线上数据库的,这种时候怎么办?测试就无法进行了吗?

Mock就是为了解决这个问题而产生的

上述那个场景,我们分清我们需要测试的核心逻辑,而不是测试被依赖的组件或者方法,那么我们可以Mock掉这些依赖,让其返回一个可以预期的值。例如需要DB依赖的时候,Mock一个Dao,需要线上组件依赖的时候,Mock一个线上组件。

我们如果 mock 一个方法的意图是什么:

  1. 在特定输入参数的情况下期待需要的输出结果(返回值)
  2. 在方法抛出某种类型异常调用者作出的反应

3. 上手使用

3.1. 首先导包

<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

 

3.2. 创建个Mock对象

既然已经明白了Mock的用途,那就明白Mock本质是创造个假对象,伪装使用


@Test

public void createMockObject() {

    // 使用 mock 静态方法创建 Mock 对象.

    Map map = mock(Map.class);

    Assert.assertTrue(map instanceof Map);



    // mock 方法不仅可以 Mock 接口类, 还可以 Mock 具体的类型.

    HashMap mock = mock(HashMap.class);

    Assert.assertTrue(mock instanceof Map);

    Assert.assertTrue(mock instanceof HashMap);

}

3.3. 配置Mock对象的行为

@Test

public void configMock() {

     

    Map map = mock(Map.class);

    //当调用map.size()方法时候,返回100

    when(map.size()).thenReturn(100);

    Assert.assertEquals(map.size(), 100);


    //当调用map.put(1,2)方法时候,返回true,参数要匹配

    when(map.put(1,2)).thenReturn(true);   

    Assert.assertTrue(map.put(1,2));


    //当调用map.get(1)方法时候,抛空指针

    doThrow(new NullPointException()).when(map).get(1);


    //表示调用size()方法什么都不做,个人觉得可以用在依赖组件或者依赖方法返回void的情况下

    doNothing().when(map).size();


    map.size();

    verify(map, times(1)).size();  //verify检测方法调用,这表明size方法调用一次



}

上述只是Mockito一些常规的方法,感觉也够用了,如果需要其他方法可以看看api见名知意或者看看文档

 

3.4. 部分模拟spy


@Test

public void testSpy() {

    List list = new LinkedList();

    List spy = spy(list);


    // 对 spy.size() 进行定制.

    when(spy.size()).thenReturn(100);


    spy.add("one");

    spy.add("two");


    // 因为我们没有对 get(0), get(1) 方法进行定制,所有这两个调用的是真实方法

    Assert.assertEquals(spy.get(0), "one");

    Assert.assertEquals(spy.get(1), "two");

    Assert.assertEquals(spy.size(), 100);

}

个人一般都采用部分模拟,模拟关键

有可能你要测试的方法名为A,A中调用B方法,而B方法是个要mock的,那么只需要when(spy.B()).thenReturn(xx);即可,无需自己调用,方法中调用也会触发mock

 

3.5. 捕获参数

一个方法调用过程中,传递的参数也可以被捕获

@Test

public void testCaptureArgument() {

    String param = "test";  //字符串参数

    List mockObject = mock(List.class);//mock一个list

    ArgumentCaptor<String> paramObject = ArgumentCaptor.forClass(String.class); //捕获参数的对象

    mockObject.add(param); //mock对象执行add方法,将test添加进其中

    verify(mockObject).addAll(paramObject.capture());//捕获参数

    Assert.assertEquals("test", paramObject.getValue()); //断言验证

}

 

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务