一,简介
1.1 单元测试的特点
- 配合断言使用(杜绝 System.out )
- 可重复执行
- 不依赖环境
- 不会对数据产生影响
- spring 的上下文环境不是必须的
- 一般都需要配合 mock 类框架来实现
1.2 mock 类框架使用场景
要进行测试的方法存在外部依赖(如 db, redis, 第三方接口调用等), 为了能够专注于对该方法(单元)的逻辑进行测试,就希望能虚拟出外部依赖,避免外部依赖成为测试的阻塞项,一般都是测试 service 层即可。
1.3 常用 mock类框架
mock 类框架;用于 mock 外部依赖
1.3.1 mockito
名称:ito: input to output
官网: https://site.mockito.org
官网文档: https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html
限制:老版本对于 fianl class, final method, static method, private method 均不能被 mockito mock, 目前已支持final class, final method, static method 的 mock, 具体可以参考官网
原理:bytebuddy, 教程: https://www.bilibili.com/video/BV1G24y1a7bd
1.3.2 easymock
1.3.3 powermock
官网:https://github.com/powermock/powermock
与mockito的版本支持关系:https://gitee.com/mirrors/powermock/wikis/Mockito#supported-versions 对 mockito 或 easymock 的增强
1.3.4 JMockit
二,mockito 的单独使用
2.1 mock 对象与 spy 对象
| 方法插桩 | 方法不插桩 | 作用对象 | 最佳实践 | |
|---|---|---|---|---|
| mock 对象 | 执行插桩逻辑 | 返回mock对象的默认值 | 类,接口 | 被测试类或其他依赖 |
| spy 对象 | 执行插桩逻辑 | 调用真实方法 | 类,接口 | 被测试类 |
2.2 初始化 mock/spy 对象的方式
| 方法一 | 方法二 | 方法三 | |
|---|---|---|---|
| junit4 | @RunWith(MockitoJUnitRunner.class) + @Mock等注解 | Mockito.mock(X.class)等静态方法 | MockitoAnnotations.openMocks(this)+@Mock等注解 |
| junit5 | @ExtendWith(MockitoExtension.class) + @Mock等注解 |
示例

/**
* 初始化 mock/spy 对象的方式有三种,第一种
* @author zhangdaowen
*/
@ExtendWith(MockitoExtension.class)
public class InitMockOrSpyMethod1 {
@Mock
private UserService mockUserService;
@Spy
private UserService spyUserService;
@Test
public void test1() {
// true 判断某对象是不是mock对象
System.out.println(" " + Mockito.mockingDetails(mockUserService).isMock().isMOck());
// false
System.out.println(""+Mockito.mockingDetails(mockUserService).isMock().isSpy());
System.out.println(""+Mockito.mockingDetails(spyUserService).isMock());
System.out.println(""+Mockito.mockingDetails(spyUserService).isMock());
}
}
/**
* 初始化 mock/spy 对象的方式有三种,第二种
* @author zhangdaowen
*/
public class InitMockOrSpyMethod2 {
private UserService mockUserService;
private UserService spyUserService;
@BeforeEach
public void init() {
mockUserService = Mockito.mock(UserService.class);
spyUserService = Mockito.spy(UserService.class);
}
@Test
public void test1() {
// true 判断某对象是不是mock对象
System.out.println(" " + Mockito.mockingDetails(mockUserService).isMock().isMOck());
// false
System.out.println(""+Mockito.mockingDetails(mockUserService).isMock().isSpy());
System.out.println(""+Mockito.mockingDetails(spyUserService).isMock());
System.out.println(""+Mockito.mockingDetails(spyUserService).isMock());
}
}
/**
* 初始化 mock/spy 对象的方式有三种,第三种
* @author zhangdaowen
*/
public class InitMockOrSpyMethod3 {
@Mock
private UserService mockUserService;
@Spy
private UserService spyUserService;
@BeforeEach
public void init() {
MockitoAnnotations.openMocks(this);
}
@Test
public void test1() {
// true 判断某对象是不是mock对象
System.out.println(" " + Mockito.mockingDetails(mockUserService).isMock().isMOck());
// false
System.out.println(""+Mockito.mockingDetails(mockUserService).isMock().isSpy());
System.out.println(""+Mockito

最低0.47元/天 解锁文章
6257

被折叠的 条评论
为什么被折叠?



