Springboot集成JUnit5優(yōu)雅進行單元測試的示例
為什么使用JUnit5
- JUnit4被廣泛使用,但是許多場景下使用起來語法較為繁瑣,JUnit5中支持lambda表達式,語法簡單且代碼不冗余。
- JUnit5易擴展,包容性強,可以接入其他的測試引擎。
- 功能更強大提供了新的斷言機制、參數化測試、重復性測試等新功能。
- ps:開發(fā)人員為什么還要測試,單測寫這么規(guī)范有必要嗎?其實單測是開發(fā)人員必備技能,只不過很多開發(fā)人員開發(fā)任務太重導致調試完就不管了,沒有系統化得單元測試,單元測試在系統重構時能發(fā)揮巨大的作用,可以在重構后快速測試新的接口是否與重構前有出入。
簡介
如圖,JUnit5結構如下:
- JUnit Platform: 這是Junit提供的平臺功能模塊,通過它,其它的測試引擎都可以接入Junit實現接口和執(zhí)行。
- JUnit JUpiter:這是JUnit5的核心,是一個基于JUnit Platform的引擎實現,它包含許多豐富的新特性來使得自動化測試更加方便和強大。
- JUnit Vintage:這個模塊是兼容JUnit3、JUnit4版本的測試引擎,使得舊版本的自動化測試也可以在JUnit5下正常運行。
依賴引入
我們以SpringBoot2.3.1為例,引入如下依賴,防止使用舊的junit4相關接口我們將其依賴排除。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency>
常用注解
- @BeforeEach:在每個單元測試方法執(zhí)行前都執(zhí)行一遍
- @BeforeAll:在每個單元測試方法執(zhí)行前執(zhí)行一遍(只執(zhí)行一次)
- @DisplayName("商品入庫測試"):用于指定單元測試的名稱
- @Disabled:當前單元測試置為無效,即單元測試時跳過該測試
- @RepeatedTest(n):重復性測試,即執(zhí)行n次
- @ParameterizedTest:參數化測試,
- @ValueSource(ints = {1, 2, 3}):參數化測試提供數據
斷言
JUnit Jupiter提供了強大的斷言方法用以驗證結果,在使用時需要借助java8的新特性lambda表達式,均是來自org.junit.jupiter.api.Assertions包的static方法。
assertTrue與assertFalse用來判斷條件是否為true或false
@Test @DisplayName("測試斷言equals") void testEquals() { assertTrue(3 < 4); }
assertNull與assertNotNull用來判斷條件是否為·null
@Test @DisplayName("測試斷言NotNull") void testNotNull() { assertNotNull(new Object()); }
assertThrows用來判斷執(zhí)行拋出的異常是否符合預期,并可以使用異常類型接收返回值進行其他操作
@Test @DisplayName("測試斷言拋異常") void testThrows() { ArithmeticException arithExcep = assertThrows(ArithmeticException.class, () -> { int m = 5/0; }); assertEquals("/ by zero", arithExcep.getMessage()); }
assertTimeout用來判斷執(zhí)行過程是否超時
@Test @DisplayName("測試斷言超時") void testTimeOut() { String actualResult = assertTimeout(ofSeconds(2), () -> { Thread.sleep(1000); return "a result"; }); System.out.println(actualResult); }
assertAll是組合斷言,當它內部所有斷言正確執(zhí)行完才算通過
@Test @DisplayName("測試組合斷言") void testAll() { assertAll("測試item商品下單", () -> { //模擬用戶余額扣減 assertTrue(1 < 2, "余額不足"); }, () -> { //模擬item數據庫扣減庫存 assertTrue(3 < 4); }, () -> { //模擬交易流水落庫 assertNotNull(new Object()); } ); }
重復性測試
在許多場景中我們需要對同一個接口方法進行重復測試,例如對冪等性接口的測試。
JUnit Jupiter通過使用@RepeatedTest(n)指定需要重復的次數
@RepeatedTest(3) @DisplayName("重復測試") void repeatedTest() { System.out.println("調用"); }
參數化測試
參數化測試可以按照多個參數分別運行多次單元測試這里有點類似于重復性測試,只不過每次運行傳入的參數不用。需要使用到@ParameterizedTest,同時也需要@ValueSource提供一組數據,它支持八種基本類型以及String和自定義對象類型,使用極其方便。
@ParameterizedTest @ValueSource(ints = {1, 2, 3}) @DisplayName("參數化測試") void paramTest(int a) { assertTrue(a > 0 && a < 4); }
內嵌測試
JUnit5提供了嵌套單元測試的功能,可以更好展示測試類之間的業(yè)務邏輯關系,我們通常是一個業(yè)務對應一個測試類,有業(yè)務關系的類其實可以寫在一起。這樣有利于進行測試。而且內聯的寫法可以大大減少不必要的類,精簡項目,防止類爆炸等一系列問題。
@SpringBootTest @AutoConfigureMockMvc @DisplayName("Junit5單元測試") public class MockTest { //.... @Nested @DisplayName("內嵌訂單測試") class OrderTestClas { @Test @DisplayName("取消訂單") void cancelOrder() { int status = -1; System.out.println("取消訂單成功,訂單狀態(tài)為:"+status); } } }
以上就是Springboot集成JUnit5優(yōu)雅進行單元測試的示例的詳細內容,更多關于Springboot 單元測試的資料請關注腳本之家其它相關文章!
相關文章
spring使用WebSocket注入service層失敗問題及解決
這篇文章主要介紹了spring使用WebSocket注入service層失敗問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07springboot配置文件屬性變量引用方式${}和@@用法及區(qū)別說明
這篇文章主要介紹了springboot配置文件屬性變量引用方式${}和@@用法及區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03淺談SpringMVC HandlerInterceptor詭異問題排查
這篇文章主要介紹了淺談SpringMVC HandlerInterceptor詭異問題排查,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05mybatis整合springboot報BindingException:Invalid?bound?stateme
這篇文章主要給大家介紹了關于mybatis整合springboot報BindingException:Invalid?bound?statement?(not?found)異常的解決辦法,這個錯誤通常是由于Mapper文件中的statement?id與Java代碼中的方法名不一致導致的,需要的朋友可以參考下2024-01-01