spring boot 单元测试JUnit5使用Mockito模拟Mock数据调用
好大一批新用法,大家静下心来好好看看吧
1. spring boot 使用 Mockito.when().thenReturn()模拟返回值
Mockito 是一种 Java mock 框架,他主要就是用来做 mock 测试的,他可以模拟任何 Spring 管理的 bean、模拟方法的返回值、模拟抛出异常…等,他同时也会记录调用这些模拟方法的参数、调用顺序,从而可以校验出这个 mock 对象是否有被正确的顺序调用,以及按照期望的参数被调用
SpringBoot 目前内建的是 Mockito 框架文章来源:https://www.toymoban.com/news/detail-553074.html
1)测试mockito.when设置固定值ID=1
/**
* mockito.when设置固定值ID=1
*/
@Test
void mockito_1L() {
User user = new User();
user.setId(1L);
// 配置userService的模拟行为,mock拦截了userService的真实行为,查询Id=1时,会模拟返回user
Mockito.when(userService.selectById(1L)).thenReturn(user);
JsonResult query = testUserController.query(user);
Assertions.assertEquals(user, query.getData());
}
2)测试mockito.when_AnyLong 设置任意Long值
/**
* 测试mockito.when_AnyLong 设置任意Long值
*/
@Test
void mockito_AnyLong() {
User mockUser = new User();
mockUser.setId(1L);
mockUser.setUsername("我是mock用户名");
// 配置userService的模拟行为,mock拦截了userService的真实行为,查询任意ID时,会模拟返回user
// 打桩,会拦截userService.selectById的方法
Mockito.when(userService.selectById(Mockito.anyLong())).thenReturn(mockUser);
// 查询ID=2L的
User user1 = new User();
user1.setId(1L);
JsonResult query = testUserController.query(user1);
Assertions.assertEquals(mockUser, query.getData());
// 查询ID=2L的
User user2 = new User();
user2.setId(2L);
JsonResult query2 = testUserController.query(user2);
Assertions.assertEquals(mockUser, query2.getData());
// 查询出来的结果,都是mockUser
}
3)测试mockito.when_AnyLong,测试调用多个参数的方法
当传入两个参数,其中一个参数采用任意参数时,指定参数需要matchers来对比,比如Mcokito.eq(“123456”)文章来源地址https://www.toymoban.com/news/detail-553074.html
/**
* 测试mockito.when_AnyLong,测试调用多个参数的方法
*/
@Test
void mockito_AnyLong2() {
User mockUser = new User();
mockUser.setId(1L);
mockUser.setUsername("我是mock用户名");
mockUser.setPassword("123456");
// 当传入两个参数,其中一个参数采用任意参数时,指定参数需要matchers来对比
// 当传入任意用户名字符串,和123456密码时,返回mock用户,否则返回null
Mockito.when(userService.addUser2Params(Mockito.anyString(), Mockito.eq("123456")))
.thenReturn(mockUser);
// controller去调用
JsonResult jsonResult = testUserController
.addUser2Params("xXxxXxx", mockUser.getPassword());
User user = (User) jsonResult.getData();
// 匹配上了,返回值与mockUser相同
Assertions.assertEquals(mockUser, user);
JsonResult jsonResult1 = testUserController.addUser2Params("xXxxXxx", "xX");
User user1 = (User) jsonResult1.getData();
// 不匹配,返回值null与mockUser就相同了
Assertions.assertNotEquals(mockUser, user1);
}
4)测试mockito.when_any(User.class) 设置对象
/**
* 测试mockito.when_any(User.class) 设置对象
*/
@Test
void mockito_AnyClass() {
// 打桩,拦截userService.addUserSynchronizedGood方法,传入任意User对象,都会返回true
Mockito.when(userService.addUserSynchronizedGood(Mockito.any(User.class)))
.thenReturn(true);
// 增加good1
User user1 = new User();
user1.setId(1L);
user1.setUsername("good1");
JsonResult add1 = testUserController.addUserSynchronizedGood(user1);
Assertions.assertEquals(true, add1.getData());
// 增加good2
User user2 = new User();
user2.setId(2L);
user1.setUsername("good2");
JsonResult add2 = testUserController.addUserSynchronizedGood(user2);
Assertions.assertEquals(true, add2.getData());
// 返回结果,都是mockUser
}
5)测试mockito.when_特定的对象的值
/**
* 测试mockito.when_特定的对象的值
*/
@Test
void mockito_Object() {
User params = new User();
params.setUsername("good1");
// 一旦一个参数是任意匹配,其他参数都必须是任意匹配
// 打桩,拦截userService.addUserSynchronizedGood方法,传入good1对象,都会返回true
// Mockito.when(userService.addUserSynchronizedGood(Mockito.eq(params))).thenReturn(true);
Mockito.when(userService.addUserSynchronizedGood(params)).thenReturn(true);
// 增加good1
User user1 = new User();
user1.setUsername("good1");
JsonResult add1 = testUserController.addUserSynchronizedGood(user1);
Assertions.assertEquals(true, add1.getData());
// 增加good2
User user2 = new User();
user2.setUsername("good2");
JsonResult add2 = testUserController.addUserSynchronizedGood(user2);
Assertions.assertNotEquals(true, add2.getData());
// 返回结果,都是mockUser
}
2. spring boot 使用mockito.when_模拟返回异常
1)thenThrow 模拟有返回值方法的异常返回
/**
* mockito.when_thenReturn 模拟返回异常
*/
@Test
void mockito_thenReturn() {
User params = new User();
params.setUsername("bad1");
// 当bad1时,模拟抛出异常
Mockito.when(userService.addUserSynchronizedGood(params))
.thenThrow(new RuntimeException("bad1异常"));
// 增加good1
User user1 = new User();
user1.setUsername("good1");
JsonResult add1 = testUserController.addUserSynchronizedGood(user1);
Assertions.assertEquals(false, add1.getData());
// 增加bad1
User user2 = new User();
user2.setUsername("bad1");
Assertions.assertThrows(RuntimeException.class,
() -> testUserController.addUserSynchronizedGood(user2), "错误了,没有产生异常");
}
2)doThrow 模拟没有返回值方法的异常返回
/**
* mockito.doThrow().when 没有返回值的方法模拟返回异常
*/
@Test
void mockito_toThrow() {
User params = new User();
params.setUsername("bad");
// 当userService.addUser(params),值是bad时,会模拟抛出异常
Mockito.doThrow(new RuntimeException("没有返回值的bad异常"))
.when(userService).addUser(params);
// 增加bad,会有异常
User user1 = new User();
user1.setUsername("bad");
Assertions.assertThrows(RuntimeException.class,
() -> testUserController.addUser(user1), "错误了,没有产生异常");
// 增加good,不会触发异常
User user2 = new User();
user2.setUsername("good");
Assertions.assertDoesNotThrow(() ->
testUserController.addUserSynchronizedGood(user2), "错误了,产生异常了");
}
3. spring boot 使用 mockito_verify 校验验证
1) mockito_verify 校验验证本次测试调用过哪些方法,调用了多少次
/**
* mockito_verify 校验验证本次测试调用过哪些方法,调用了多少次
*/
@Test
void mockito_verify() {
userService.selectById(3L);
userService.selectById(3L);
userService.selectById(3L);
// 验证selectById是否调用了3次
Mockito.verify(userService, Mockito.times(3)).selectById(Mockito.eq(3L));
User user = new User();
user.setId(3L);
testUserController.query(user);
testUserController.query(user);
testUserController.query(user);
// 验证selectById是否调用了6次
Mockito.verify(userService, Mockito.times(6)).selectById(Mockito.eq(3L));
}
2) mockito.inOrder.verify,按照顺序校验
/**
* mockito.inOrder.verify,按照顺序校验
*/
@Test
void mockito_inOrder() {
userService.selectById(1L);
userService.selectById(3L);
userService.selectById(2L);
// 按顺序校验
InOrder inOrder = Mockito.inOrder(userService);
// 校验1次1L
inOrder.verify(userService).selectById(1L);
// 之后调了1次3L
inOrder.verify(userService).selectById(3L);
// 之后又调了1次2L
inOrder.verify(userService).selectById(2L);
}
4. 用到的TestUserController
package space.goldchen.springboot.test;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import space.goldchen.springboot.common.JsonResult;
import space.goldchen.springboot.entity.User;
import space.goldchen.springboot.service.UserService;
/**
* 单元测试,由单元测试来验证测试
*
* @author chenzhao
* @create 2023-05-24 17:00
*/
@RestController
@RequestMapping("/test")
@RequiredArgsConstructor
public class TestUserController {
private final UserService userService;
/**
* 新增用户
*
* @param user
* @return
*/
@PostMapping("/add")
public JsonResult addUserSynchronizedGood(@RequestBody User user) {
boolean b = userService.addUserSynchronizedGood(user);
return new JsonResult(b);
}
/**
* 新增用户,没有加锁的
*
* @param user
* @return
*/
@PostMapping("/addUser")
public JsonResult addUser(@RequestBody User user) {
userService.addUser(user);
return new JsonResult("添加了用户");
}
/**
* 查询用户
*
* @param user
* @return
*/
@GetMapping("/queryById")
public JsonResult query(@RequestBody User user) {
User user1 = userService.selectById(user.getId());
return new JsonResult(user1);
}
/**
* 查询用户
*
* @param id
* @return
*/
@GetMapping("/queryById2")
public JsonResult query2(Long id) {
User user1 = userService.selectById(id);
return new JsonResult(user1);
}
/**
* 修改用户
*
* @param user
* @return
*/
@PutMapping("/updateById")
public JsonResult update(@RequestBody User user) {
boolean b = userService.updateSelective(user);
return new JsonResult(b);
}
/**
* 删除用户
*
* @param user
* @return
*/
@DeleteMapping("/updateById")
public JsonResult delete(@RequestBody User user) {
boolean b = userService.del(user);
return new JsonResult(b);
}
}
5.用到的UserService
package space.goldchen.springboot.service;
import space.goldchen.springboot.entity.User;
/**
* @author chenzhao
* @create 2023-05-20 9:56
*/
public interface UserService {
User selectByUsername(String username);
User selectById(Long id);
void addUser(User user);
/**
* 同步锁,添加用户
* @param user
*/
boolean addUserSynchronizedBad(User user);
/**
* 同步锁,添加用户
* @param user
*/
boolean addUserSynchronizedGood(User user);
/**
* 更新用户
* @param user
* @return
*/
boolean updateSelective(User user);
/**
* 删除用户
* @param user
* @return
*/
boolean del(User user);
}
到了这里,关于spring boot 单元测试JUnit5使用Mockito模拟Mock数据调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!