spring boot 單元測試JUnit5使用Mockito模擬Mock數(shù)據(jù)調(diào)用
好大一批新用法,大家靜下心來好好看看吧
1. spring boot 使用 Mockito.when().thenReturn()模擬返回值
Mockito 是一種 Java mock 框架,他主要就是用來做 mock 測試的,他可以模擬任何 Spring 管理的 bean、模擬方法的返回值、模擬拋出異常…等,他同時(shí)也會(huì)記錄調(diào)用這些模擬方法的參數(shù)、調(diào)用順序,從而可以校驗(yàn)出這個(gè) mock 對(duì)象是否有被正確的順序調(diào)用,以及按照期望的參數(shù)被調(diào)用
SpringBoot 目前內(nèi)建的是 Mockito 框架文章來源:http://www.zghlxwxcb.cn/news/detail-553074.html
1)測試mockito.when設(shè)置固定值ID=1
/**
* mockito.when設(shè)置固定值ID=1
*/
@Test
void mockito_1L() {
User user = new User();
user.setId(1L);
// 配置userService的模擬行為,mock攔截了userService的真實(shí)行為,查詢Id=1時(shí),會(huì)模擬返回user
Mockito.when(userService.selectById(1L)).thenReturn(user);
JsonResult query = testUserController.query(user);
Assertions.assertEquals(user, query.getData());
}
2)測試mockito.when_AnyLong 設(shè)置任意Long值
/**
* 測試mockito.when_AnyLong 設(shè)置任意Long值
*/
@Test
void mockito_AnyLong() {
User mockUser = new User();
mockUser.setId(1L);
mockUser.setUsername("我是mock用戶名");
// 配置userService的模擬行為,mock攔截了userService的真實(shí)行為,查詢?nèi)我釯D時(shí),會(huì)模擬返回user
// 打樁,會(huì)攔截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());
// 查詢出來的結(jié)果,都是mockUser
}
3)測試mockito.when_AnyLong,測試調(diào)用多個(gè)參數(shù)的方法
當(dāng)傳入兩個(gè)參數(shù),其中一個(gè)參數(shù)采用任意參數(shù)時(shí),指定參數(shù)需要matchers來對(duì)比,比如Mcokito.eq(“123456”)文章來源地址http://www.zghlxwxcb.cn/news/detail-553074.html
/**
* 測試mockito.when_AnyLong,測試調(diào)用多個(gè)參數(shù)的方法
*/
@Test
void mockito_AnyLong2() {
User mockUser = new User();
mockUser.setId(1L);
mockUser.setUsername("我是mock用戶名");
mockUser.setPassword("123456");
// 當(dāng)傳入兩個(gè)參數(shù),其中一個(gè)參數(shù)采用任意參數(shù)時(shí),指定參數(shù)需要matchers來對(duì)比
// 當(dāng)傳入任意用戶名字符串,和123456密碼時(shí),返回mock用戶,否則返回null
Mockito.when(userService.addUser2Params(Mockito.anyString(), Mockito.eq("123456")))
.thenReturn(mockUser);
// controller去調(diào)用
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) 設(shè)置對(duì)象
/**
* 測試mockito.when_any(User.class) 設(shè)置對(duì)象
*/
@Test
void mockito_AnyClass() {
// 打樁,攔截userService.addUserSynchronizedGood方法,傳入任意User對(duì)象,都會(huì)返回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());
// 返回結(jié)果,都是mockUser
}
5)測試mockito.when_特定的對(duì)象的值
/**
* 測試mockito.when_特定的對(duì)象的值
*/
@Test
void mockito_Object() {
User params = new User();
params.setUsername("good1");
// 一旦一個(gè)參數(shù)是任意匹配,其他參數(shù)都必須是任意匹配
// 打樁,攔截userService.addUserSynchronizedGood方法,傳入good1對(duì)象,都會(huì)返回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());
// 返回結(jié)果,都是mockUser
}
2. spring boot 使用mockito.when_模擬返回異常
1)thenThrow 模擬有返回值方法的異常返回
/**
* mockito.when_thenReturn 模擬返回異常
*/
@Test
void mockito_thenReturn() {
User params = new User();
params.setUsername("bad1");
// 當(dāng)bad1時(shí),模擬拋出異常
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), "錯(cuò)誤了,沒有產(chǎn)生異常");
}
2)doThrow 模擬沒有返回值方法的異常返回
/**
* mockito.doThrow().when 沒有返回值的方法模擬返回異常
*/
@Test
void mockito_toThrow() {
User params = new User();
params.setUsername("bad");
// 當(dāng)userService.addUser(params),值是bad時(shí),會(huì)模擬拋出異常
Mockito.doThrow(new RuntimeException("沒有返回值的bad異常"))
.when(userService).addUser(params);
// 增加bad,會(huì)有異常
User user1 = new User();
user1.setUsername("bad");
Assertions.assertThrows(RuntimeException.class,
() -> testUserController.addUser(user1), "錯(cuò)誤了,沒有產(chǎn)生異常");
// 增加good,不會(huì)觸發(fā)異常
User user2 = new User();
user2.setUsername("good");
Assertions.assertDoesNotThrow(() ->
testUserController.addUserSynchronizedGood(user2), "錯(cuò)誤了,產(chǎn)生異常了");
}
3. spring boot 使用 mockito_verify 校驗(yàn)驗(yàn)證
1) mockito_verify 校驗(yàn)驗(yàn)證本次測試調(diào)用過哪些方法,調(diào)用了多少次
/**
* mockito_verify 校驗(yàn)驗(yàn)證本次測試調(diào)用過哪些方法,調(diào)用了多少次
*/
@Test
void mockito_verify() {
userService.selectById(3L);
userService.selectById(3L);
userService.selectById(3L);
// 驗(yàn)證selectById是否調(diào)用了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);
// 驗(yàn)證selectById是否調(diào)用了6次
Mockito.verify(userService, Mockito.times(6)).selectById(Mockito.eq(3L));
}
2) mockito.inOrder.verify,按照順序校驗(yàn)
/**
* mockito.inOrder.verify,按照順序校驗(yàn)
*/
@Test
void mockito_inOrder() {
userService.selectById(1L);
userService.selectById(3L);
userService.selectById(2L);
// 按順序校驗(yàn)
InOrder inOrder = Mockito.inOrder(userService);
// 校驗(yàn)1次1L
inOrder.verify(userService).selectById(1L);
// 之后調(diào)了1次3L
inOrder.verify(userService).selectById(3L);
// 之后又調(diào)了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;
/**
* 單元測試,由單元測試來驗(yàn)證測試
*
* @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);
}
到了這里,關(guān)于spring boot 單元測試JUnit5使用Mockito模擬Mock數(shù)據(jù)調(diào)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!