Mockito使用

前言

在Spring单元测试中,如果不想生成的对象受Spring管理的话,就可以使用Mock注解,为了减少单测与spring框架的耦合,并且尽量不使用真实对象进行模拟,可以使用@InjectMocks和@Mock注解

Mockito使用

生成@Mock、@Spy备注的mock对象,用

typescript 复制代码
@BeforeEach
	void setUp() {
		MockitoAnnotations.openMocks(this);
	}

定义一个实体类

vbnet 复制代码
@Data
public class UserQuery {

    
    private Long id;


    private String account;


    private String username;

    private Long deptId;


    private List<Long> roleIds;
    
    private String password;
    

}

定义一个service接口

scss 复制代码
public Boolean save(UserQuery userQuery) {
		UserDTO userDTO = new UserDTO();
		userDTO.setUsername(userQuery.getAccount());
		R<Boolean> result = remoteUserAdminService.isExist(userDTO);
		if (!Objects.equals(result.getCode(), CommonConstants.SUCCESS)) {
			throw new BussException("判断用户名是否存在错误");
		}
		if (result.getData()) {
			throw new BussException("用户名已存在");
		}
		userDTO.setNickName(userQuery.getUsername());
		result = remoteUserAdminService.user(userDTO);
		if (!Objects.equals(result.getCode(), CommonConstants.SUCCESS)) {
			throw new BussException("保存用户异常");
		}
		return result.getData();
	}

测试单元如下

scss 复制代码
@DisplayName("用户模块测试")
public class UserServiceImplTest {

	@InjectMocks
	private UserServiceImpl userService;

	@Mock
	private RemoteUserService remoteUserService;


	@Mock
	private RemoteUserAdminService remoteUserAdminService;

	@BeforeEach
	void setUp() {
		MockitoAnnotations.openMocks(this);
	}

	@Nested
	@DisplayName("新建用户单元测试")
	public class UserAddTest {

		@Test
		@DisplayName("保存用户,查询用户名是否存在,三方系统返回调用失败 => 返回异常")
		void save_1_test() {
			UserQuery userQuery = new UserQuery();
			userQuery.setUsername("aa");
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(userQuery.getAccount());
			R<Boolean> result = R.restResult(null, 1, "操作失败");
			Mockito.when(remoteUserAdminService.isExist(Mockito.any(UserDTO.class))).thenReturn(result);
			Assertions.assertThrows(BussException.class, () -> {
				userService.save(userQuery);
			});
			Mockito.verify(remoteUserAdminService, times(1)).isExist(Mockito.any(UserDTO.class));
		}

		@Test
		@DisplayName("保存用户,查询用户名是否存在,三方系统返回用户名已经存在 => 返回异常")
		void save_2_test() {
			UserQuery userQuery = new UserQuery();
			userQuery.setUsername("aa");			
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(userQuery.getAccount());
			R<Boolean> result = R.restResult(true, 0, "操作成功");
			Mockito.when(remoteUserService.isExist(Mockito.any(UserDTO.class))).thenReturn(result);
			Assertions.assertThrows(BussException.class, () -> {
				userService.save(userQuery);
			});
			Mockito.verify(remoteUserService, times(1)).isExist(Mockito.any(UserDTO.class));
		}

		@Test
		@DisplayName("保存用户,三方系统返回保存异常 => 返回异常")
		void save_3_test() {
			UserQuery userQuery = new UserQuery();
			userQuery.setUsername("aa");
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(userQuery.getAccount());
			R<Boolean> result = R.restResult(false, 0, "操作成功");
			Mockito.when(remoteUserService.isExist(Mockito.any(UserDTO.class))).thenReturn(result);
			R<Boolean> saveR = R.restResult(false, 1, "操作失败");
			Mockito.when(remoteUserService.user(Mockito.any(UserDTO.class))).thenReturn(saveR);
			Assertions.assertThrows(BussException.class, () -> {
				userService.save(userQuery);
			});
			Mockito.verify(remoteUserService, times(1)).isExist(Mockito.any(UserDTO.class));
			Mockito.verify(remoteUserService, times(1)).user(Mockito.any(UserDTO.class));
		}

		@Test
		@DisplayName("保存用户,三方系统返回成功 => 保存用户成功")
		void save_4_test() {
			UserQuery userQuery = new UserQuery();
			userQuery.setUsername("aa");
			UserDTO userDTO = new UserDTO();
			userDTO.setUsername(userQuery.getAccount());
			R<Boolean> result = R.restResult(false, 0, "操作成功");
			Mockito.when(remoteUserService.isExist(Mockito.any(UserDTO.class))).thenReturn(result);
			R<Boolean> saveR = R.ok(true, "操作成功");
			Mockito.when(remoteUserService.user(Mockito.any(UserDTO.class))).thenReturn(saveR);
			Boolean isSuccess = userService.save(userQuery);
			Mockito.verify(remoteUserService, times(1)).isExist(Mockito.any(UserDTO.class));
			Mockito.verify(remoteUserService, times(1)).user(Mockito.any(UserDTO.class));
			Assertions.assertTrue(isSuccess);
		}

	}

}

其中

Mockito.when

Mockito.when是模拟一个方法返回值,如

ini 复制代码
Mockito.when(remoteUserService.isExist(Mockito.any(UserDTO.class))).thenReturn(result);
			R<Boolean> saveR = R.ok(true, "操作成功");

模拟方法中调用isExist,返回result结果,Mockito.any(UserDTO.class)是传入一个UserDTO值

Mockito.verify

Mockito.verify(remoteUserService, times(1)),是验证方法中remoteUserService是不是被被用了一次

总结

在单元测试中,Mockito可以模拟出对象不受Spring框架影响,这样在没有Bean的注入和管理下,启动和验证就比较快,当然,写单元测试的时候,具体问题具体分析

相关推荐
不够优雅7 分钟前
【Concept Plugin 3】轻量级插件化解决方案|动态类加载
java·spring boot·spring cloud
Victor3568 分钟前
Redis(100)如何防止Redis的数据丢失?
后端
Victor3569 分钟前
Redis(101)Redis为什么是单线程的?
后端
程序员三明治1 小时前
选 Redis Stream 还是传统 MQ?队列选型全攻略(适用场景、优缺点与实践建议)
java·redis·后端·缓存·rocketmq·stream·队列
Cosmoshhhyyy4 小时前
《Effective Java》解读第5条:优先考虑依赖注入来引用资源
java
.柒宇.5 小时前
力扣hot100----15.三数之和(java版)
java·数据结构·算法·leetcode
程序员卷卷狗6 小时前
JVM 调优实战:从线上问题复盘到精细化内存治理
java·开发语言·jvm
cj6341181506 小时前
【MySQL】mysqldump使用方法
java·后端
JIngJaneIL6 小时前
停车场管理|停车预约管理|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·停车场管理系统
杰克尼7 小时前
二分查找为什么总是写错
java·数据结构·算法