Mockito+PowerMock+Junit單元測(cè)試用途解析
一、單元測(cè)試用途
1、日常開發(fā)團(tuán)隊(duì)要求規(guī)范,需要對(duì)開發(fā)需求代碼進(jìn)行單元測(cè)試并要求行覆蓋率達(dá)到要求,DevOps流水線也會(huì)開設(shè)相關(guān)門禁閥值阻斷代碼提交,一般新增代碼行覆蓋率80%左右。
二、Mock測(cè)試介紹
1、Mock是為了解決不同的單元之間由于耦合而難于開發(fā)、測(cè)試的問題。所以,Mock既能出現(xiàn)在單元測(cè)試中,也會(huì)出現(xiàn)在集成測(cè)試、系統(tǒng)測(cè)試過程中。Mock 最大的功能是幫你把單元測(cè)試的耦合分解開,如果你的代碼對(duì)另一個(gè)類或者接口有依賴,它能夠幫你模擬這些依賴,并幫你驗(yàn)證所調(diào)用的依賴的行為。

2、Mock 測(cè)試就是在測(cè)試活動(dòng)中,對(duì)于某些不容易構(gòu)造或者不容易獲取的比較復(fù)雜的數(shù)據(jù)/場(chǎng)景,用一個(gè)虛擬的對(duì)象(Mock對(duì)象)來創(chuàng)建用于測(cè)試的測(cè)試方法。
3、Mock重要作用
Mock是為了解決不同的單元之間由于耦合而難于開發(fā)、測(cè)試的問題。所以,Mock既能出現(xiàn)在單元測(cè)試中,也會(huì)出現(xiàn)在集成測(cè)試、系統(tǒng)測(cè)試過程中。
Mock 最大的功能是幫你把單元測(cè)試的耦合分解開,如果你的代碼對(duì)另一個(gè)類或者接口有依賴,它能夠幫你模擬這些依賴,并幫你驗(yàn)證所調(diào)用的依賴的行為。
三、Mock測(cè)試所需依賴
1、主要引入mockito-core/powermock-core
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.9</version>
<scope>test</scope>
</dependency>Mockito和PowerMock都是單元測(cè)試模擬框架,用于模擬被測(cè)試類的依賴項(xiàng)。Mockito基于動(dòng)態(tài)代理的方式實(shí)現(xiàn),而PowerMock在Mockito基礎(chǔ)上增加了類加載器以及字節(jié)碼篡改技術(shù),使其可以實(shí)現(xiàn)對(duì)private/static/final方法的Mock
四、Mock的核心功能

1、Mock對(duì)象創(chuàng)建
Mockito.mock(List.class); // Mock對(duì)象創(chuàng)建
public class VerifyMockExample {
@Test
public void testVerifyMock() {
List<String> mockList = Mockito.mock(List.class);
// 調(diào)用Mock對(duì)象的方法
mockList.add("testCode");
mockList.size();
// 驗(yàn)證mockList.add("test")是否被調(diào)用過一次
Mockito.verify(mockList,Mockito.times(1)).add("testCode");
// 驗(yàn)證size()方法是否被調(diào)用過
Mockito.verify(mockList,Mockito.times(1)).size();
Assert.assertFalse(mockList.size()==1);
}
}verify系列方法
Mockito.verify/Mockito.times()驗(yàn)證調(diào)用次數(shù)
·verify(mock).methodCall():驗(yàn)證方法被調(diào)用
· verify(mock, times(n)).methodCall():驗(yàn)證方法被調(diào)用n次
· verify(mock, never()).methodCall():驗(yàn)證方法從未被調(diào)用
或者是通過注解來實(shí)現(xiàn)創(chuàng)建
@Mock
private UserInfoMapper mockUserInfoMapper;
@InjectMocks
private UserInfoServiceImpl userInfoServiceImplUnderTest; @Test
public void testVerifyMock2(){
List<String> mockList = Mockito.mock(List.class);
mockList.add("Code1");
mockList.add("Code2");
// 驗(yàn)證是否調(diào)用兩次
Mockito.verify(mockList,Mockito.times(2));
}// 驗(yàn)證這個(gè)方法從沒有被調(diào)用過 Mockito.verify(userMapper, Mockito.never()).getUserById(1); userMapper.getUserById(1); // 驗(yàn)證這個(gè)方法至少調(diào)用了1次 Mockito.verify(userMapper, Mockito.atLeastOnce()).getUserById(1); userMapper.getUserById(1); // 驗(yàn)證當(dāng)前方法調(diào)用了2次 Mockito.verify(userMapper, Mockito.times(2)).getUserById(1);
Mockito.when()使用when和thenReturn方法配置Mock對(duì)象的行為
Mockito.when( 對(duì)象.方法名 ).thenReturn( 自定義結(jié)果) //當(dāng)調(diào)用了某個(gè) Mock 對(duì)象的方法時(shí),就回傳我們想要的自定義結(jié)果。
thenReturn系列方法
//當(dāng)使用任何整數(shù)值調(diào)用 userService 的 getUserById 方法時(shí),就回傳一個(gè)名字為 I'm mock 3 的 User 對(duì)象。
Mockito.when(userService.getUserById(Mockito.anyInt)).thenReturn( newUser( 3, "I'm mock"));
//限制只有當(dāng)參數(shù)的數(shù)字是 3 時(shí),才會(huì)回傳名字為 I'm mock 3 的 user 對(duì)象。
Mockito.when(userService.getUserById( 3)).thenReturn( newUser( 3, "I'm mock"));
//當(dāng)調(diào)用 userService 的 insertUser 方法時(shí),不管傳進(jìn)來的 user 是什么,都回傳 100。
Mockito.when(userService.insertUser(Mockito.any(User.class))).thenReturn( 100);
thenThrow系列方法
//當(dāng)調(diào)用 userService 的 getUserById 時(shí)的參數(shù)是 8 時(shí),拋出一個(gè) RuntimeException。
Mockito.when(userService.getUserById( 8)).thenThrow( new RuntimeException( "mock throw exception"));
//如果方法沒有返回值的話(即方法定義為 public void myMethod {...}),要改用 doThrow 拋出 Exception。
Mockito.doThrow( new RuntimeException( "mock throw exception")).when(userService.print);
@Test
public void testVerifyMock3(){
List<String> mockList = Mockito.mock(List.class);
// 設(shè)置Mock對(duì)象的預(yù)期行為
Mockito.when(mockList.get(0)).thenReturn("mockedValue");
// 斷言驗(yàn)證返回值
Assert.assertEquals("mockedValue",mockList.get(0));
}實(shí)戰(zhàn)案例:測(cè)試一個(gè)UserInfoServiceImpl層saveUser()方法.
原始方法:
@Transactional
@Override
public void saveUser(UserInfo userInfo){
userInfoMapper.saveUser(userInfo);
}單元測(cè)試:
@Test
public void testSaveUser() {
// Setup
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("userName");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
// Run the test
userInfoServiceImplUnderTest.saveUser(userInfo);
// Verify the results
Mockito.verify(mockUserInfoMapper).saveUser(new UserInfo());
}原始方法:
@Override
public List<UserInfo> queryListByUserName(String userName) {
return userInfoMapper.queryListByUserName(userName);
}單元測(cè)試方法:
@Test
public void testQueryListByUserName() {
// Setup
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("userName");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> expectedResult = Arrays.asList(userInfo);
// Configure UserInfoMapper.queryListByUserName(...).
final UserInfo userInfo1 = new UserInfo();
userInfo1.setId(0);
userInfo1.setUserName("userName");
userInfo1.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo1.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> userInfos = Arrays.asList(userInfo1);
when(mockUserInfoMapper.queryListByUserName("userName")).thenReturn(userInfos);
// Run the test
final List<UserInfo> result = userInfoServiceImplUnderTest.queryListByUserName("userName");
// Verify the results
assertThat(result).isEqualTo(expectedResult);
}
@Test
public void testQueryListByUserName_UserInfoMapperReturnsNoItems() {
// Setup
when(mockUserInfoMapper.queryListByUserName("userName")).thenReturn(Collections.emptyList());
// Run the test
final List<UserInfo> result = userInfoServiceImplUnderTest.queryListByUserName("userName");
// Verify the results
assertThat(result).isEqualTo(Collections.emptyList());
}原始方法:
@Override
public List<UserInfo> queryUserInfoList(String createTime, List<Integer> idList) {
return userInfoMapper.queryListByIds(createTime,idList);
}單元測(cè)試方法:
@Test
public void testQueryUserInfoList() {
// Setup
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("userName");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> expectedResult = Arrays.asList(userInfo);
// Configure UserInfoMapper.queryListByIds(...).
final UserInfo userInfo1 = new UserInfo();
userInfo1.setId(0);
userInfo1.setUserName("userName");
userInfo1.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo1.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> userInfos = Arrays.asList(userInfo1);
when(mockUserInfoMapper.queryListByIds("createTime", Arrays.asList(0))).thenReturn(userInfos);
// Run the test
final List<UserInfo> result = userInfoServiceImplUnderTest.queryUserInfoList("createTime", Arrays.asList(0));
// Verify the results
assertThat(result).isEqualTo(expectedResult);
}
@Test
public void testQueryUserInfoList_UserInfoMapperReturnsNoItems() {
// Setup
when(mockUserInfoMapper.queryListByIds("createTime", Arrays.asList(0))).thenReturn(Collections.emptyList());
// Run the test
final List<UserInfo> result = userInfoServiceImplUnderTest.queryUserInfoList("createTime", Arrays.asList(0));
// Verify the results
assertThat(result).isEqualTo(Collections.emptyList());
}原始方法:Controller層,MockMvc
mockMvc.perform(request):執(zhí)行一個(gè)HTTP請(qǐng)求,并返回ResultActions對(duì)象。
ResultActions.andExpect(expected):驗(yàn)證請(qǐng)求的處理結(jié)果,如狀態(tài)碼、響應(yīng)體等。
ResultActions.andDo(handler):處理請(qǐng)求的響應(yīng),如將響應(yīng)體寫入文件等。
ResultActions.andReturn():返回已執(zhí)行請(qǐng)求的結(jié)果,以便直接訪問結(jié)果。
MockMvc.perform(request).andExpect(expected).andDo(handler).andReturn():鏈?zhǔn)秸{(diào)用,執(zhí)行請(qǐng)求、驗(yàn)證結(jié)果并處理響應(yīng),返回結(jié)果。
@Slf4j
@RestController
public class UserInfoController {
@Autowired
private UserInfoService userInfoService;
/**
* 查詢?nèi)苛斜?
* @return
*/
@RequestMapping("/boot/query/users")
public List<UserInfo> getUserInfoList(){
List<UserInfo> list = userInfoService.list();
return list;
}
/**
* 保存用戶信息
* @return
*/
@RequestMapping("/boot/save/user")
public String saveUser(){
try {
UserInfo user=new UserInfo();
user.setUserName("MyBatis Log Free");
userInfoService.save(user);
} catch (Exception e) {
log.error("save user error", e);
throw new GlobalException("save user error");
}
return "success";
}
@RequestMapping("/boot/query/users/ids")
public List<UserInfo> getUserInfoListIds(){
List<Integer> list = Arrays.asList(1, 3, 5);
String createTime="2022-09-05 15:11:21";
List<UserInfo> userInfos = userInfoService.queryUserInfoList(createTime,list);
return userInfos;
}
@RequestMapping("/boot/query/users/like")
public List<UserInfo> getUserInfoListLike(){
List<UserInfo> infoList = userInfoService.queryListByUserName("A");
return infoList;
}
@RequestMapping("/boot/save/userinfo")
public void saveUserInfo(){
UserInfo userInfo = new UserInfo();
userInfo.setId(5);
userInfo.setUserName("Puck");
Date startTime = new Date();
Date endTime = new Date();
userInfo.setCreateTime(startTime);
userInfo.setUpdateTime(endTime);
userInfoService.saveUser(userInfo);
}
}單元測(cè)試方法如下:
@RunWith(SpringRunner.class)
@WebMvcTest(UserInfoController.class)
public class UserInfoControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserInfoService mockUserInfoService;
@Test
public void testGetUserInfoList() throws Exception {
// Setup
// Configure UserInfoService.list(...).
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("MyBatis Log Free");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> userInfos = Arrays.asList(userInfo);
when(mockUserInfoService.list()).thenReturn(userInfos);
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
// assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
}
@Test
public void testGetUserInfoList_UserInfoServiceReturnsNoItems() throws Exception {
// Setup
when(mockUserInfoService.list()).thenReturn(Collections.emptyList());
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("[]");
}
@Test
public void testSaveUser() throws Exception {
// Setup
when(mockUserInfoService.save(new UserInfo())).thenReturn(false);
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/save/user")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
verify(mockUserInfoService).save(new UserInfo());
}
@Test
public void testGetUserInfoListIds() throws Exception {
// Setup
// Configure UserInfoService.queryUserInfoList(...).
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("MyBatis Log Free");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> userInfos = Arrays.asList(userInfo);
when(mockUserInfoService.queryUserInfoList("2022-09-05 15:11:21", Arrays.asList(0))).thenReturn(userInfos);
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/ids")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
}
@Test
public void testGetUserInfoListIds_UserInfoServiceReturnsNoItems() throws Exception {
// Setup
when(mockUserInfoService.queryUserInfoList("2022-09-05 15:11:21", Arrays.asList(0)))
.thenReturn(Collections.emptyList());
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/ids")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("[]");
}
@Test
public void testGetUserInfoListLike() throws Exception {
// Setup
// Configure UserInfoService.queryListByUserName(...).
final UserInfo userInfo = new UserInfo();
userInfo.setId(0);
userInfo.setUserName("MyBatis Log Free");
userInfo.setCreateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
userInfo.setUpdateTime(new GregorianCalendar(2020, Calendar.JANUARY, 1).getTime());
final List<UserInfo> userInfos = Arrays.asList(userInfo);
when(mockUserInfoService.queryListByUserName("A")).thenReturn(userInfos);
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/like")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
}
@Test
public void testGetUserInfoListLike_UserInfoServiceReturnsNoItems() throws Exception {
// Setup
when(mockUserInfoService.queryListByUserName("A")).thenReturn(Collections.emptyList());
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/query/users/like")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("[]");
}
@Test
public void testSaveUserInfo() throws Exception {
// Setup
// Run the test
final MockHttpServletResponse response = mockMvc.perform(get("/boot/save/userinfo")
.accept(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
// Verify the results
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
assertThat(response.getContentAsString()).isEqualTo("expectedResponse");
verify(mockUserInfoService).saveUser(new UserInfo());
}
}@Mock用于模擬不屬于 Spring 上下文的對(duì)象,而@MockBean用于模擬屬于 Spring Boot 應(yīng)用程序中的 Spring 上下文的對(duì)象。@MockBean提供與 Spring Boot 測(cè)試框架的無縫集成,并允許在測(cè)試期間用模擬對(duì)象輕松替換實(shí)際 bean
Mockito提供了多種參數(shù)匹配器(Matchers)用于更靈活的驗(yàn)證和配置行為:
import static org.mockito.ArgumentMatchers.*; when(mockRepository.findById(anyInt())).thenReturn(Optional.of(user)); verify(mockRepository).findById(eq(1));
常見的匹配器包括:
·any():匹配任何參數(shù)
· anyInt():匹配任何整數(shù)參數(shù)
· eq(value):匹配特定值
· isNull():匹配null值
· notNull():匹配非null值
Mock異常
Mockito.when(userMapper.getUserById(Mockito.anyInt())).thenThrow(new RuntimeException("運(yùn)行時(shí)錯(cuò)誤"));
Assertions.assertThrowsExactly(RuntimeException.class, () -> userMapper.getUserById(1));
// 對(duì)于沒有返回值的方法,不能使用thenThrow()來拋出異常,可以使用doThrow()來拋出異常。
Mockito.doThrow(new RuntimeException("運(yùn)行時(shí)錯(cuò)誤")).when(userMapper).getUserById(1);
Assertions.assertThrowsExactly(RuntimeException.class, () -> userMapper.getUserById(1));@MockBean 是 Spring Boot 提供的注解,它用于在測(cè)試中創(chuàng)建一個(gè) mock 對(duì)象,并將其注入到 Spring 上下文中,替換掉原來的真實(shí) Bean。 需要使用SpringJUnit4ClassRunner.class之類的注解
@Mock: 用于代替Mockito.mock創(chuàng)建mock對(duì)象,創(chuàng)建一個(gè)Mock實(shí)例,需要基于JUnit5環(huán)境。@InjectMocks: 創(chuàng)建一個(gè)實(shí)例,其余用@Mock(或@Spy)注解創(chuàng)建的mock將被注入到用該實(shí)例中。
你要測(cè)試哪個(gè)類(如TemplateUserServiceImpl ),那么就用 @InjectMocks注解;被測(cè)試的類中通過 @Autowired注解注入了幾個(gè),那么測(cè)試類里面就用@Mock注解創(chuàng)建幾個(gè)實(shí)例!
原始代碼:
@Service
public class TemplateUserServiceImpl implements TemplateUserService {
@Autowired
private NamedParameterJdbcTemplate jdbcTemplate;
@Transactional
@Override
public void saveUser() {
UserInfo userInfo = new UserInfo();
userInfo.setId(7);
userInfo.setUserName("Boot");
Date startTime = new Date();
Date endTime = new Date();
userInfo.setCreateTime(startTime);
userInfo.setUpdateTime(endTime);
// JdbcTemplate的寫入datetime,使用in方式
// String sql="insert into user_info(user_name,create_time,update_time) values(:user_name,:create_time,:update_time)";
String sql="insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)";
SqlParameterSource sqlParameterSource=new BeanPropertySqlParameterSource(userInfo);
// HashMap paramMap = new HashMap<>();
// paramMap.put("user_name",userInfo.getUserName());
// paramMap.put("create_time",userInfo.getCreateTime());
// paramMap.put("update_time",userInfo.getUpdateTime());
// jdbcTemplate.update(sql,paramMap);
jdbcTemplate.update(sql,sqlParameterSource);
}
}對(duì)應(yīng)單元測(cè)試代碼:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class TemplateUserServiceImplTest {
@Mock
private NamedParameterJdbcTemplate mockJdbcTemplate;
@InjectMocks
private TemplateUserServiceImpl templateUserServiceImplUnderTest;
@Test
public void testSaveUser() {
// Setup
// Run the test
templateUserServiceImplUnderTest.saveUser();
// Verify the results
verify(mockJdbcTemplate).update(
eq("insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)"),
any(SqlParameterSource.class));
}
@Test
public void testSaveUser_NamedParameterJdbcTemplateThrowsDataAccessException() {
// Setup
when(mockJdbcTemplate.update(
eq("insert into user_info(user_name,create_time,update_time) values(:userName,:createTime,:updateTime)"),
any(SqlParameterSource.class))).thenThrow(DataAccessException.class);
// Run the test
assertThatThrownBy(() -> templateUserServiceImplUnderTest.saveUser()).isInstanceOf(DataAccessException.class);
}
}@MockBean 和 @SpyBean和@Spy以及@Mock的使用場(chǎng)景和區(qū)別

五、單元測(cè)試生成插件
1、IDEA中安裝Squaretest插件使用
文件右鍵即可生成對(duì)應(yīng)單元測(cè)試,需要修改測(cè)試用例,滿足業(yè)務(wù)訴求。


2、破解插件過程
idea版本:

下載字節(jié)碼編譯工具:jclasslib。

JAR包路徑:C:\Users\Administrator\AppData\Roaming\JetBrains\IntelliJIdea2023.3\plugins\Squaretest

說明:不用版本的Squaretest插件的jar包名稱或許不一樣,找空間最大的那個(gè),約15M左右的那個(gè)。


最后一步點(diǎn)擊保存按鈕,選擇“overwrite”時(shí),此時(shí)一定要將idea關(guān)閉,否則會(huì)保存失敗的.

最后破解成功,可以正常使用。

到此這篇關(guān)于Mockito+PowerMock+Junit單元測(cè)試的文章就介紹到這了,更多相關(guān)Mockito+PowerMock+Junit單元測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java測(cè)試框架Mockito的簡(jiǎn)明教程
- Java單元測(cè)試Mockito的使用詳解
- 怎樣使用PowerMockito 測(cè)試靜態(tài)方法
- SpringBoot 單元測(cè)試實(shí)戰(zhàn)(Mockito,MockBean)
- SpringBoot+JUnit5+MockMvc+Mockito單元測(cè)試的實(shí)現(xiàn)
- Spring Boot 整合 Mockito提升Java單元測(cè)試的高效實(shí)踐案例
- Java Springboot 后端使用Mockito庫進(jìn)行單元測(cè)試流程分析
- 在SpringBoot環(huán)境中使用Mockito進(jìn)行單元測(cè)試的示例詳解
相關(guān)文章
教你用springboot連接mysql并實(shí)現(xiàn)增刪改查
今天教各位小伙伴用springboot連接mysql并實(shí)現(xiàn)增刪改查功能,文中有非常詳細(xì)的步驟及代碼示例,對(duì)正在學(xué)習(xí)Java的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05
Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼
這篇文章主要介紹了Java通過socket客戶端保持連接服務(wù)端實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
創(chuàng)建網(wǎng)關(guān)項(xiàng)目(Spring Cloud Gateway)過程詳解
這篇文章主要介紹了創(chuàng)建網(wǎng)關(guān)項(xiàng)目(Spring Cloud Gateway)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
java 數(shù)據(jù)結(jié)構(gòu)中棧結(jié)構(gòu)應(yīng)用的兩個(gè)實(shí)例
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)中棧結(jié)構(gòu)應(yīng)用的兩個(gè)實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06
Java數(shù)據(jù)結(jié)構(gòu)之棧的線性結(jié)構(gòu)詳解
從數(shù)據(jù)結(jié)構(gòu)上看棧和隊(duì)列都是線性表,不過是兩種特殊的線性表,棧只允許在的一端進(jìn)行插人或刪除操作,而隊(duì)列只允許在表的一端進(jìn)行插人操作、而在另一端進(jìn)行刪除操作,這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之棧的線性結(jié)構(gòu)的相關(guān)資料,需要的朋友可以參考下2021-08-08
Java實(shí)現(xiàn)新建有返回值的線程的示例詳解
本文主要介紹了一個(gè)Java多線程的例題,題目是:使用ThreadLocal管理一號(hào)和二號(hào)線程,分別存入100元,在三號(hào)線程中使用利用一號(hào)和二號(hào)的計(jì)算結(jié)果來算出賬戶的實(shí)際金額。感興趣的可以了解一下2022-09-09

