更優(yōu)雅的單元測試——Spring Boot 集成 JUnit5

一、 為什么使用JUnit5

  • JUnit4被廣泛使用,但是許多場景下使用起來語法較為繁瑣鞭达,JUnit5中支持lambda表達式,語法簡單且代碼不冗余皇忿。
  • JUnit5易擴展畴蹭,包容性強,可以接入其他的測試引擎鳍烁。
  • 功能更強大提供了新的斷言機制叨襟、參數(shù)化測試、重復性測試等新功能幔荒。
  • ps:開發(fā)人員為什么還要測試糊闽,單測寫這么規(guī)范有必要嗎?其實單測是開發(fā)人員必備技能爹梁,只不過很多開發(fā)人員開發(fā)任務太重導致調(diào)試完就不管了右犹,沒有系統(tǒng)化得單元測試,單元測試在CI/CD姚垃、編譯打包念链、回歸測試、系統(tǒng)重構時能發(fā)揮巨大的作用积糯,可以在重構后快速測試新的接口是否與原設計有出入掂墓,改動是否破壞了原有邏輯?

二看成、 JUnit5簡介

JUnit5組成

如圖君编,JUnit5結構如下:

  • JUnit Platform:這是Junit提供的平臺功能模塊,通過它绍昂,其它的測試引擎都可以接入Junit實現(xiàn)接口和執(zhí)行啦粹。
  • JUnit JUpiter:這是JUnit5的核心,是一個基于JUnit Platform的引擎實現(xiàn)窘游,它包含許多豐富的新特性來使得自動化測試更加方便和強大。
  • 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:參數(shù)化測試于置,
  • @ValueSource(ints = {1, 2, 3}):參數(shù)化測試提供數(shù)據(jù)

五茧吊、 斷言

JUnit Jupiter提供了強大的斷言方法用以驗證結果,在使用時需要借助java8的新特性lambda表達式八毯,均是來自org.junit.jupiter.api.Assertions包的static方法搓侄。

assertTrueassertFalse用來判斷條件是否為truefalse


@Test
@DisplayName("測試斷言equals")
void testEquals() {
    assertTrue(3 < 4);
}

assertNullassertNotNull用來判斷條件是否為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是組合斷言话速,當它內(nèi)部所有斷言正確執(zhí)行完才算通過

@Test
@DisplayName("測試組合斷言")
void testAll() {
    assertAll("測試item商品下單",
            () -> {
                //模擬用戶余額扣減
                assertTrue(1 < 2, "余額不足");
            },
            () -> {
                //模擬item數(shù)據(jù)庫扣減庫存
                assertTrue(3 < 4);
            },
            () -> {
                //模擬交易流水落庫
                assertNotNull(new Object());
            }
    );
}

五讶踪、 重復性測試

在許多場景中我們需要對同一個接口方法進行重復測試,例如對冪等性接口的測試泊交。

JUnit Jupiter通過使用@RepeatedTest(n)指定需要重復的次數(shù)

@RepeatedTest(3)
@DisplayName("重復測試")
void repeatedTest() {
    System.out.println("調(diào)用");
}
重復性測試

六乳讥、 參數(shù)化測試

參數(shù)化測試可以按照多個參數(shù)分別運行多次單元測試這里有點類似于重復性測試,只不過每次運行傳入的參數(shù)不用廓俭。需要使用到@ParameterizedTest雏婶,同時也需要@ValueSource提供一組數(shù)據(jù),它支持八種基本類型以及String和自定義對象類型白指,使用極其方便留晚。

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
@DisplayName("參數(shù)化測試")
void paramTest(int a) {
    assertTrue(a > 0 && a < 4);
}

七、 內(nèi)嵌測試

JUnit5提供了嵌套單元測試的功能告嘲,可以更好展示測試類之間的業(yè)務邏輯關系错维,我們通常是一個業(yè)務對應一個測試類,有業(yè)務關系的類其實可以寫在一起橄唬。這樣有利于進行測試赋焕。而且內(nèi)聯(lián)的寫法可以大大減少不必要的類,精簡項目仰楚,防止類爆炸等一系列問題隆判。

@SpringBootTest
@AutoConfigureMockMvc
@DisplayName("Junit5單元測試")
public class MockTest {
    //....
    @Nested
    @DisplayName("內(nèi)嵌訂單測試")
    class OrderTestClas {
        @Test
        @DisplayName("取消訂單")
        void cancelOrder() {
            int status = -1;
            System.out.println("取消訂單成功,訂單狀態(tài)為:"+status);
        }
    }
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市僧界,隨后出現(xiàn)的幾起案子侨嘀,更是在濱河造成了極大的恐慌,老刑警劉巖捂襟,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咬腕,死亡現(xiàn)場離奇詭異,居然都是意外死亡葬荷,警方通過查閱死者的電腦和手機涨共,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門纽帖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人举反,你說我怎么就攤上這事懊直。” “怎么了火鼻?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵室囊,是天一觀的道長。 經(jīng)常有香客問我凝危,道長波俄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任蛾默,我火速辦了婚禮懦铺,結果婚禮上,老公的妹妹穿的比我還像新娘支鸡。我一直安慰自己冬念,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布牧挣。 她就那樣靜靜地躺著急前,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瀑构。 梳的紋絲不亂的頭發(fā)上裆针,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音寺晌,去河邊找鬼世吨。 笑死,一個胖子當著我的面吹牛呻征,可吹牛的內(nèi)容都是我干的耘婚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼陆赋,長吁一口氣:“原來是場噩夢啊……” “哼沐祷!你這毒婦竟也來了?” 一聲冷哼從身側響起攒岛,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤赖临,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后阵子,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體思杯,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年挠进,在試婚紗的時候發(fā)現(xiàn)自己被綠了色乾。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡领突,死狀恐怖暖璧,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情君旦,我是刑警寧澤澎办,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站金砍,受9級特大地震影響局蚀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜恕稠,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一琅绅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鹅巍,春花似錦千扶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至敛苇,卻和暖如春妆绞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枫攀。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工括饶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脓豪。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓巷帝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扫夜。 傳聞我的和親對象是個殘疾皇子楞泼,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容