Java單元測(cè)試實(shí)踐(Mock)
概念
單元測(cè)試,用于檢查和驗(yàn)證程序中的各個(gè)單元(通常是函數(shù)、方法或類)是否按照預(yù)期工作(是否符合預(yù)期)。
庫
| 庫 | 解釋 |
|---|---|
| JUnit | 單元測(cè)試框架,提供了一組注解和斷言來編寫和運(yùn)行測(cè)試 |
| Spring Test和SpringBootTest | 提供了一些方便的工具和注解來進(jìn)行集成測(cè)試和組件測(cè)試。 |
| AssertJ | 斷言庫,提供了豐富的斷言來編寫清晰、易讀的測(cè)試代碼。 |
| Hamcrest | 匹配器庫,用于編寫靈活和可讀的斷言。 |
| Mockito | 用于創(chuàng)建和管理模擬對(duì)象,幫助模擬外部依賴、行為和狀態(tài)。 |
注解
@SpringBootTest:用于加載Spring應(yīng)用程序上下文。@AutoConfigureMockMvc:用于自動(dòng)配置MockMvc實(shí)例。@Transactional:開啟事務(wù)功能。@Rollback():事務(wù)回滾,默認(rèn)true。@ParameterizedTest:用于支持參數(shù)化測(cè)試。@CsvSource、@ValueSource、@MethodSource@Mock:創(chuàng)建模擬對(duì)象。@MockBean:創(chuàng)建模擬對(duì)象,會(huì)注入到 Spring 上下文。@Spy:創(chuàng)建真實(shí)對(duì)象,并可以部分模擬該對(duì)象的行為。@InjectMocks:標(biāo)記一個(gè)待測(cè)對(duì)象(被測(cè)試類的對(duì)象),用于注入被測(cè)試類中的依賴(注入模擬對(duì)象)。
Assertions類
在JUnit測(cè)試中,Assertions類提供了一系列用于驗(yàn)證測(cè)試結(jié)果的靜態(tài)方法。
assertEquals(expected, actual):驗(yàn)證兩個(gè)值是否相等。適用于比較基本數(shù)據(jù)類型、對(duì)象或數(shù)組等。
assertEquals(5, result); // 比較整數(shù)值
assertEquals("expected", result); // 比較字符串值
assertEquals(expectedObject, actualObject); // 比較對(duì)象
assertEquals(expectedArray, actualArray); // 比較數(shù)組
assertTrue(condition):驗(yàn)證給定的條件是否為真。assertFalse(condition):驗(yàn)證給定的條件是否為假。assertNull(object):驗(yàn)證給定對(duì)象是否為空。assertNotNull(object):驗(yàn)證給定對(duì)象是否不為空。assertSame(expected, actual):驗(yàn)證兩個(gè)對(duì)象引用是否指向同一個(gè)對(duì)象。assertNotSame(unexpected, actual):驗(yàn)證兩個(gè)對(duì)象引用是否指向不同的對(duì)象。assertThrows(expectedType, executable):驗(yàn)證代碼塊是否拋出了指定類型的異常。
單元測(cè)試步驟
Navigate → Test :自動(dòng)生成測(cè)試類。
注意:Controller層的單元測(cè)試,可以使用MockMvc模擬HTTP請(qǐng)求。
- 準(zhǔn)備測(cè)試數(shù)據(jù):在測(cè)試方法之前,準(zhǔn)備好必要的測(cè)試數(shù)據(jù),包括輸入?yún)?shù)、模擬的依賴對(duì)象等。
- 模擬依賴對(duì)象:使用
Mockito等框架模擬Controller、Service層依賴的其他對(duì)象,例如Repository、外部服務(wù)等。
若不使用模擬對(duì)象,直接@Autowired注入測(cè)試即可。
- 調(diào)用被測(cè)試的方法:在測(cè)試方法中調(diào)用
Controller、Service層的方法,傳入準(zhǔn)備好的測(cè)試數(shù)據(jù)。 - 驗(yàn)證行為:使用斷言驗(yàn)證方法的行為和返回結(jié)果是否符合預(yù)期
Mock
在面向?qū)ο蟪绦蛑校?strong>模擬對(duì)象(mock object)是以可控方式模擬真實(shí)對(duì)象行為的假對(duì)象。
在編程過程中,通常通過模擬一些輸入數(shù)據(jù),來驗(yàn)證程序是否達(dá)到預(yù)期結(jié)果。
如果在單元測(cè)試中無法使用真實(shí)對(duì)象,可采用模擬對(duì)象進(jìn)行替代。
MockMvc:模擬HTTP請(qǐng)求
MockMvc Spring提供的用于模擬HTTP請(qǐng)求的工具,它允許模擬請(qǐng)求并驗(yàn)證控制器的行為和響應(yīng)。
在單元測(cè)試和集成測(cè)試中,MockMvc 可以用來測(cè)試控制器的端到端行為,而不需要啟動(dòng)整個(gè)應(yīng)用程序服務(wù)器。
MockMvc構(gòu)造
三種方法
mockMvc = MockMvcBuilders.standaloneSetup(new Testontroller()).build();mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();@AutoConfigureMockMvc注解用于自動(dòng)配置MockMvc實(shí)例。
MockMvc使用
mockMvc.perform執(zhí)行一個(gè)請(qǐng)求,返回值ResultActions。
MockMvcRequestBuilders.get(“/xx/xx”)構(gòu)造一個(gè)get請(qǐng)求。
MockMvcRequestBuilders類提供的各種靜態(tài)方法構(gòu)建不同類型的請(qǐng)求,如GET、POST、PUT、DELETE等。contentType設(shè)置發(fā)送的數(shù)據(jù)格式accept設(shè)置返回的數(shù)據(jù)格式param添加請(qǐng)求傳值header設(shè)置請(qǐng)求頭
ResultActions.andExpect添加執(zhí)行完成后的斷言。
- 使用斷言是判斷結(jié)果是否符合期望。
- 使用
MockMvcResultMatchers類提供的各種靜態(tài)方法構(gòu)建斷言,例如status()、content()、header()等。 - 使用
MockMvcResultMatchers.status().isOk()來斷言預(yù)期的HTTP狀態(tài)碼是否為200(OK)。
ResultActions.andDo添加一個(gè)結(jié)果處理器,表示要對(duì)結(jié)果做點(diǎn)什么事情。比如處使用print()輸出整個(gè)響應(yīng)結(jié)果信息。
ResultActions.andReturn表示執(zhí)行完成后返回相應(yīng)的結(jié)果。
@Mock
@Mock是 Mockito 框架中的注解,用于創(chuàng)建模擬對(duì)象。@Mock只能用于普通的單元測(cè)試(例如,不涉及 Spring 應(yīng)用程序上下文的測(cè)試),通常與MockitoJUnitRunner或MockitoAnnotations.initMocks()配合使用。- 它創(chuàng)建的模擬對(duì)象是純粹的模擬對(duì)象,不會(huì)受到 Spring 上下文的影響,因此不會(huì)自動(dòng)注入到 Spring 容器中。
@MockBean
@MockBean是 Spring Boot Test 模塊中的注解,用于創(chuàng)建模擬對(duì)象,并將其注入到 Spring 上下文中,以便在集成測(cè)試中使用。@MockBean可以用于測(cè)試 Spring 上下文中的組件,例如服務(wù)、存儲(chǔ)庫、控制器等。- 它創(chuàng)建的模擬對(duì)象是由 Spring 管理的 Bean,可以被自動(dòng)注入到其他 Spring Bean 中。
@Mock和@MockBean區(qū)別(是否注入)
@Mock用于創(chuàng)建純粹的模擬對(duì)象@MockBean用于在 Spring 上下文中創(chuàng)建模擬對(duì)象,并將其注入到其他 Spring Bean 中,以便在集成測(cè)試中使用。
@Spy
@Spy 是 Mockito 框架中的一個(gè)注解,用于創(chuàng)建一個(gè)真實(shí)對(duì)象,并部分模擬該對(duì)象的行為。
與 @Mock 注解不同,@Spy 注解創(chuàng)建的對(duì)象是真實(shí)對(duì)象,但可以選擇性地模擬部分方法的行為。
@InjectMocks和@Mock
@InjectMocks:標(biāo)記一個(gè)待測(cè)對(duì)象(被測(cè)試類的對(duì)象),用于注入被測(cè)試類中的依賴。@Mock用于創(chuàng)建模擬對(duì)象,@InjectMocks用于將這些 模擬對(duì)象 注入 到被測(cè)試對(duì)象中,以便進(jìn)行單元測(cè)試。
@ParameterizedTest注解
用于支持參數(shù)化測(cè)試。為測(cè)試方法提供一組不同的參數(shù),以便多次運(yùn)行相同的測(cè)試邏輯,但使用不同的輸入?yún)?shù)。
@CsvSource
用于提供一組參數(shù)給參數(shù)化測(cè)試方法。使用逗號(hào)分隔的字符串表示多個(gè)參數(shù),每個(gè)字符串代表一個(gè)測(cè)試案例。
@ParameterizedTest
@CsvSource({"1, 1, 2", "2, 3, 5", "5, 5, 10"})
void testAddition(int a, int b, int expectedSum) {
int actualSum = a + b;
assertEquals(expectedSum, actualSum, "Sum of " + a + " and " + b + " should be " + expectedSum);
}
@ParameterizedTest 注解表示該方法是一個(gè)參數(shù)化測(cè)試方法。
@CsvSource 注解提供了一組參數(shù),每一行代表一個(gè)測(cè)試案例。
- 在這個(gè)示例中,提供了三組參數(shù),每組參數(shù)包含兩個(gè)整數(shù)和一個(gè)預(yù)期的結(jié)果。
- 參數(shù)化測(cè)試方法
testAddition()接受三個(gè)參數(shù):兩個(gè)整數(shù)和一個(gè)預(yù)期的結(jié)果。
測(cè)試方法將對(duì)這些參數(shù)執(zhí)行加法操作,并使用斷言驗(yàn)證實(shí)際的結(jié)果是否與預(yù)期的結(jié)果相匹配。
@ValueSource
用于提供基本類型或字符串類型的參數(shù)。逗號(hào)分隔多個(gè)參數(shù),每個(gè)參數(shù)代表一個(gè)測(cè)試案例。
@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void testIsPositive(int number) {
//驗(yàn)證參數(shù)是否為正數(shù)
assertTrue(number > 0);
}
@MethodSource
用于指定一個(gè)方法來提供參數(shù)給參數(shù)化測(cè)試方法。
@MethodSource 注解,可以將參數(shù)提供邏輯從測(cè)試類中抽取到一個(gè)單獨(dú)的方法中,以提高代碼的可讀性和可維護(hù)性。
@ParameterizedTest
@MethodSource("stringProvider")
void testStringLength(String input, int expectedLength) {
assertEquals(expectedLength, input.length());
}
// 參數(shù)提供邏輯 抽取到 一個(gè)單獨(dú)的方法
static Stream<Arguments> stringProvider() {
return Stream.of(
Arguments.of("apple", 5),
Arguments.of("banana", 6),
Arguments.of("orange", 6)
);
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Java 單元測(cè)試之Mockito 模擬靜態(tài)方法與私有方法最佳實(shí)踐
- Java Springboot 后端使用Mockito庫進(jìn)行單元測(cè)試流程分析
- Spring Boot 整合 Mockito提升Java單元測(cè)試的高效實(shí)踐案例
- Java通過PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
- Java單元測(cè)試Powermockito和Mockito使用總結(jié)
- Java單元測(cè)試Mockito的使用詳解
- Java mockito單元測(cè)試實(shí)現(xiàn)過程解析
- 深入學(xué)習(xí)Java單元測(cè)試(Junit+Mock+代碼覆蓋率)
相關(guān)文章
Spring Boot使用Druid進(jìn)行維度的統(tǒng)計(jì)和監(jiān)控
這篇文章主要介紹了Spring Boot使用Druid進(jìn)行維度的統(tǒng)計(jì)和監(jiān)控,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-04-04
springcloud微服務(wù)跨域的配置小結(jié)
本文主要介紹了springcloud微服務(wù)跨域的配置小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-12-12
解決IDEA錯(cuò)誤 Cause: java.sql.SQLException: The server time zone
這篇文章主要介紹了解決IDEA錯(cuò)誤 Cause: java.sql.SQLException: The server time zone value的問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
SpringMVC中的DispatcherServlet請(qǐng)求分析
這篇文章主要介紹了SpringMVC中的DispatcherServlet請(qǐng)求分析, DispatcherServlet作為一個(gè)Servlet,那么當(dāng)有請(qǐng)求到Tomcat等Servlet服務(wù)器時(shí),會(huì)調(diào)用其service方法,再調(diào)用到其父類GenericServlet的service方法,需要的朋友可以參考下2024-01-01
SpringBoot實(shí)現(xiàn)抽獎(jiǎng)算法的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何通過SpringBoot實(shí)現(xiàn)抽獎(jiǎng)算法,文中的示例代碼簡(jiǎn)潔易懂,具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下2023-06-06
Java設(shè)計(jì)模式編程中的工廠方法模式和抽象工廠模式
這篇文章主要介紹了Java設(shè)計(jì)模式編程中的工廠方法模式和抽象工廠模式,設(shè)計(jì)模式的建立有利于團(tuán)隊(duì)協(xié)作時(shí)代碼的共同維護(hù),需要的朋友可以參考下2016-01-01
Java?Chassis3應(yīng)用視角的配置管理技術(shù)解密
這篇文章主要為大家介紹了Java?Chassis3應(yīng)用視角的配置管理相關(guān)的機(jī)制和背后故事,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Spring Boot實(shí)現(xiàn)通用的接口參數(shù)校驗(yàn)
本文介紹基于 Spring Boot 和 JDK8 編寫一個(gè) AOP ,結(jié)合自定義注解實(shí)現(xiàn)通用的接口參數(shù)校驗(yàn)。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05

