如何用mockito+spring进行单元测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用mockito+spring进行单元测试相关的知识,希望对你有一定的参考价值。

参考技术A 它分成以下几个步骤:
建立mock;
将mock和待测试的对象连接起来;
在mock上设置预期的返回值;
开启replay模式,准备记录实际发生的调用;
进行测试;
验证测试结果,调用顺序是否正确,返回值是否符合期望;本回答被提问者和网友采纳
参考技术B 它分成以下几个步骤:
建立mock;
将mock和待测试的对象连接起来;
在mock上设置预期的返回值;
开启replay模式,准备记录实际发生的调用;
进行测试;
验证测试结果,调用顺序是否正确,返回值是否符合期望;

Mockito - JUnit + Mockito 单元测试之打桩 when().thenReturn()

什么是Mock 测试

Mock 测试就是在测试过程中,对于某些不容易构造(如 HttpServletRequest 必须在Servlet 容器中才能构造出来)或者不容易获取的对象(如 JDBC 中的ResultSet 对象,JPA的CRUDRepository,需要执行数据库操作的),用一个虚拟的对象(Mock 对象)来创建(覆盖方法返回)以便测试的测试方法。

  • JUnit 是一个单元测试框架。
  • Mockito 是用于数据模拟对象的框架。

when().thenReturn();

when( mockRepository.getMock("x") ).thenReturn( "1024" );
String mock= mockRepository.getMock("x");
assertEquals( "预期x=1024","1024", mock);

when(xxxx).thenReturn(yyyy); 是指定当执行了这个方法的时候,返回 thenReturn 的值,相当于是对模拟对象的配置过程,为某些条件给定一个预期的返回值。

HttpServletRequest request = mock(HttpServletRequest.class);
when(request.getParameter("csdn")).thenReturn("zhengkai");
assertEquals( "预期csdn=zhengkai",request.getParameter("csdn"), "zhengkai");

Stub 打桩

Mockito 中 when().thenReturn(); 这种语法来定义对象方法和参数(输入),然后在 thenReturn 中指定结果(输出)。此过程称为 Stub 打桩 。一旦这个方法被 stub 了,就会一直返回这个 stub 的值。

Stub 打桩 需要注意的是

  • 对于 static 和 final 方法, Mockito 无法对其 when(…).thenReturn(…) 操作。
  • 当我们连续两次为同一个方法使用 stub 的时候,他只会只用最新的一次。

迭代打桩

打桩支持迭代风格的返回值,第一次调用 i.next() 将返回 ”Hello”,第二次的调用会返回 ”World”。

// 第一种方式 ,都是等价的
when(i.next()).thenReturn("Hello").thenReturn("World");
// 第二种方式,都是等价的
when(i.next()).thenReturn("Hello", "World");
// 第三种方式,都是等价的
when(i.next()).thenReturn("Hello"); when(i.next()).thenReturn("World");

void如何打桩

没有返回值的 void 方法呢?不需要执行,只需要模拟跳过,写法上会有所不同,没返回值了调用 thenReturn(xxx) 肯定不行,取而代之的用 doNothing().when().notify();

doNothing().when(obj).notify();
// 或直接
when(obj).notify();

抛出异常

when(i.next()).thenThrow(new RuntimeException());
doThrow(new RuntimeException()).when(i).remove(); // void 方法的
// 迭代风格 
doNothing().doThrow(new RuntimeException()).when(i).remove(); 
// 第一次调用 remove 方法什么都不做,第二次调用抛出 RuntimeException 异常。

Any()

anyString() 匹配任何 String 参数,anyInt() 匹配任何 int 参数,anySet() 匹配任何 Set,any() 则意味着参数为任意值 any(User.class) 匹配任何 User类。

when(mockedList.get(anyInt())).thenReturn("element");   
System.out.println(mockedList.get(999));// 此时打印是 element
System.out.println(mockedList.get(777));// 此时打印是 element

以上是关于如何用mockito+spring进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mockito 模拟由 Spring 应用程序上下文创建的对象以进行单元测试覆盖?

[翻译]使用Spring Boot进行单元测试

Mockito - JUnit + Mockito 单元测试之打桩 when().thenReturn()

SpringBoot 单元测试利器——Mockito

使用 mockito 对插入方法进行单元测试

mockito单元测试