Mockito+Junit5单元测试
参考:
https://segmentfault.com/a/1190000006746409
https://waylau.com/mockito-quick-start/
1.引入依赖
下面这个最新版本匹配似乎有问题
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.7.7'
testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '3.7.7'
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter', version: '5.7.0'
改用下面的旧版本测试成功
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.18.3'
testCompile group: 'org.mockito', name: 'mockito-junit-jupiter', version: '2.18.3'
testCompile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.2.0'
2.编写测试用例
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mockito;
import java.util.*;
/**
* @author zhengqian
* @date 2021.01.22
*/
public class CommonTest {
@Test
public void createMockObject() {
// 使用 mock 静态方法创建 Mock 对象.
List mockedList = Mockito.mock(List.class);
Assertions.assertTrue(mockedList instanceof List);
// mock 方法不仅可以 Mock 接口类, 还可以 Mock 具体的类型.
ArrayList mockedArrayList = Mockito.mock(ArrayList.class);
Assertions.assertTrue(mockedArrayList instanceof List);
Assertions.assertTrue(mockedArrayList instanceof ArrayList);
}
@Test
public void configMockObject() {
List mockedList = Mockito.mock(List.class);
// 我们定制了当调用 mockedList.add("one") 时, 返回 true
Mockito.when(mockedList.add("one")).thenReturn(true);
// 当调用 mockedList.size() 时, 返回 1
Mockito.when(mockedList.size()).thenReturn(1);
Assertions.assertTrue(mockedList.add("one"));
// 因为我们没有定制 add("two"), 因此返回默认值, 即 false.
Assertions.assertFalse(mockedList.add("two"));
Assertions.assertEquals(mockedList.size(), 1);
Iterator i = Mockito.mock(Iterator.class);
Mockito.when(i.next()).thenReturn("Hello,").thenReturn("Mockito!");
String result = i.next() + " " + i.next();
//assert
Assertions.assertEquals("Hello, Mockito!", result);
}
@Test
public void testVerify() {
List mockedList = Mockito.mock(List.class);
mockedList.add("one");
mockedList.add("two");
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
Mockito.when(mockedList.size()).thenReturn(5);
Assertions.assertEquals(mockedList.size(), 5);
// mockedList.add("one") 至少被调用了 1 次(atLeastOnce)
Mockito.verify(mockedList, Mockito.atLeastOnce()).add("one");
// mockedList.add("two") 被调用了 1 次(times(1))
Mockito.verify(mockedList, Mockito.times(1)).add("two");
// mockedList.add("three times") 被调用了 3 次(times(3))
Mockito.verify(mockedList, Mockito.times(3)).add("three times");
// mockedList.isEmpty() 从未被调用(never)
Mockito.verify(mockedList, Mockito.never()).isEmpty();
}
@Test
public void testSpy() {
List list = new LinkedList();
// 使用 spy() 部分模拟对象
List spy = Mockito.spy(list);
// 对 spy.size() 进行定制.
Mockito.when(spy.size()).thenReturn(100);
spy.add("one");
spy.add("two");
// 因为我们没有对 get(0), get(1) 方法进行定制,
// 因此这些调用其实是调用的真实对象的方法.
Assertions.assertEquals(spy.get(0), "one");
Assertions.assertEquals(spy.get(1), "two");
Assertions.assertEquals(spy.size(), 100);
}
@Test
public void testCaptureArgument() {
List<String> list = Arrays.asList("1", "2");
List mockedList = Mockito.mock(List.class);
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
mockedList.addAll(list);
// 获取 mockedList.addAll 方法所传递的实参 list.
Mockito.verify(mockedList).addAll(argument.capture());
Assertions.assertEquals(2, argument.getValue().size());
Assertions.assertEquals(list, argument.getValue());
}
@Test
public void testArgumentMatcher() {
List mockedList = Mockito.mock(List.class);
//stubbing using built-in anyInt() argument matcher
Mockito.when(mockedList.get(Mockito.anyInt())).thenReturn("element");
//stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
// when(mockedList.contains(argThat(isValid()))).thenReturn("element");
//following prints "element"
System.out.println(mockedList.get(999));
}
@Test
public void testThrowAndVoid() {
List mockedList = Mockito.mock(List.class);
Mockito.when(mockedList.get(1)).thenThrow(new RuntimeException());
//following throws runtime exception
System.out.println(mockedList.get(1));
Mockito.doThrow(new RuntimeException()).when(mockedList).clear();
//following throws RuntimeException:
mockedList.clear();
}
@Test
public void testInOrder() {
// A. Single mock whose methods must be invoked in a particular order
List singleMock = Mockito.mock(List.class);
//using a single mock
singleMock.add("was added first");
singleMock.add("was added second");
//create an inOrder verifier for a single mock
InOrder inOrder = Mockito.inOrder(singleMock);
//following will make sure that add is first called with "was added first, then with "was added second"
inOrder.verify(singleMock).add("was added first");
inOrder.verify(singleMock).add("was added second");
// B. Multiple mocks that must be used in a particular order
List firstMock = Mockito.mock(List.class);
List secondMock = Mockito.mock(List.class);
//using mocks
firstMock.add("was called first");
secondMock.add("was called second");
//create inOrder object passing any mocks that need to be verified in order
InOrder inOrder2 = Mockito.inOrder(firstMock, secondMock);
//following will make sure that firstMock was called before secondMock
inOrder2.verify(firstMock).add("was called first");
inOrder2.verify(secondMock).add("was called second");
}
@Test
public void testConsecutiveStubbing() {
List mockedList = Mockito.mock(List.class);
Mockito.when(mockedList.get(0))
.thenThrow(new RuntimeException())
.thenReturn("foo");
// 精简写法
// when(mockedList.get(0)).thenReturn("one", "two", "three");
//First call: throws runtime exception:
mockedList.get(0);
//Second call: prints "foo"
System.out.println(mockedList.get(0));
//Any consecutive call: prints "foo" as well (last stubbing wins).
System.out.println(mockedList.get(0));
}
@Test
public void testCallbackStubbing() {
List mockedList = Mockito.mock(List.class);
Mockito.when(mockedList.get(Mockito.anyInt())).thenAnswer(invocation -> {
Object[] args = invocation.getArguments();
return "called with arguments: " + args;
});
//the following prints "called with arguments: foo"
System.out.println(mockedList.get(111));
}
}
使用mock注解
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
/**
* @author zhengqian
* @date 2021.01.27
*/
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserService userService;
@Test
public void testGet() {
Mockito.when(userService.get()).thenReturn("fake user");
Assertions.assertEquals(userService.get(), "fake user");
}
}
3. 其他JUnit5注解
@Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
@ParameterizedTest :表示方法是参数化测试,下方会有详细介绍
@RepeatedTest :表示方法可重复执行,下方会有详细介绍
@DisplayName :为测试类或者测试方法设置展示名称
@BeforeEach :表示在每个单元测试之前执行
@AfterEach :表示在每个单元测试之后执行
@BeforeAll :表示在所有单元测试之前执行
@AfterAll :表示在所有单元测试之后执行
@Tag :表示单元测试类别,类似于JUnit4中的@Categories
@Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
@Timeout :表示测试方法运行如果超过了指定时间将会返回错误
@ExtendWith :为测试类或测试方法提供扩展类引用
补充
如果运行test遇到以下错误:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> No tests found for given includes: [org.example.mockito.demo.service.UserServiceTest.configMockObject](filter.includeTestsMatching)
改一下IDEA配置

Mockito+Junit5单元测试的更多相关文章
- 基于Springboot+Junit+Mockito做单元测试
前言 前面的两篇文章讨论过< 为什么要写单元测试,何时写,写多细 >和<单元测试规范>,这篇文章介绍如何使用Springboot+Junit+Mockito做单元测试,案例选取 ...
- 使用Mockito进行单元测试【2】—— stub 和 高级特性[转]
一篇中介绍了Mockito的基本信息,现在接着介绍Mockito强大的stub功能 2. Mockito使用实例 5. 对连续的调用进行不同的返回 (iterator-style stubbing) ...
- 使用Mockito进行单元测试【1】——mock and verify[转]
本文转自:http://qiuguo0205.iteye.com/blog/1443344 1. 为什么使用Mockito来进行单元测试? 回答这个问题需要回答两个方面,第一个是为什么使用mock?m ...
- 使用 Mockito 辅助单元测试
了解过单元测试相关概念的人应该会清楚一个概念:一个好的单元测试应该是与环境无关的,每一个测试都是相互独立的.亦即你可以在任何地方,以任意顺序运行这些测试,最后得到的结果是一样的.但是我被测试的类/方法 ...
- 使用 Junit + Mockito 实践单元测试
一.前言 相信做过开发的同学,都多多少少写过下面的代码,很长一段时间我一直以为这就是单元测试... @SpringBootTest @RunWith(SpringRunner.class) publi ...
- powermock+mockito+testng 单元测试pom文件
0:Supported versions PowerMock version 1.7.0 and upper has experimental support of Mockito 2. A lot ...
- 单元测试系列:Mock工具之Mockito实战
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6780719.html 在实际项目中写单 ...
- 单元测试系列之五:Mock工具之Mockito实战
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6780719.html 在实际项目中写单 ...
- 单元测试系列之六:JUnit5 技术前瞻
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6868495.html JUnit ...
随机推荐
- Java 中能创建 volatile 数组吗?
能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不 是整个数组.我的意思是,如果改变引用指向的数组,将会受到 volatile 的保护, 但是如果多个线程同时改变数 ...
- 基于vue2.0的在线电影APP,
基于vue2.0构建的在线电影网[film],webpack + vue + vuex + vue-loader + keepAlive + muse-ui + cordova 全家桶,cordova ...
- 微信小程序 MinUI 组件库系列之 price 价格组件
MinUI 是基于微信小程序自定义组件特性开发而成的一套简洁.易用.高效的组件库,适用场景广,覆盖小程序原生框架.小程序组件化框架等,并且提供了高效的命令行工具.MinUI 组件库包含了很多基础的组件 ...
- 校验ip地址的格式
/*输入:strIP:ip地址 返回:如果通过验证返回true,否则返回false: */ function isIP(strIP) { if (isNull(strIP)) return false ...
- css盒子模型、垂直外边距合并
css盒子模型由四部分组成:内容(content).填充(padding).边框(border).边距(margin),其中css样式中定义的width属性是定义内容区域的宽度,正常情况下,设置了内容 ...
- zabbix 服务器500错误,解决故障。
ZABBIX 500错误,查看apache错误日志,index.php 32 line.写着语法错误!!! 到路径下打开/var/www/html/zabbix/index.php文件,定位32行,可 ...
- C语言 之 多线程编程
一.基础知识 计算机的核心是CPU,承担了所有的计算任务. 操作系统是计算机的管理者,负责任务的调度.资源的分配和管理,统领整个计算机硬件. 应用程序则是具有某种功能的程序,程序是运行于操作系统之上的 ...
- Python的组合数据类型
""" Python的组合类型: 序列类型:元素之间存在先后关系,可以通过索引来访问 列表: 元组: 字符串: 映射类型:用键值来表示数据 字典: 集合类型:元素是无序的 ...
- php进制转换
前端html页面代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- OpenHarmony 3.1 Beta版本关键特性解析——探秘隐式查询
(以下内容来自开发者分享,不代表 OpenHarmony 项目群工作委员会观点) 徐浩 隐式查询是 OpenAtom OpenHarmony(以下简称"OpenHarmony" ...