Junit 單元測試?
????????JUnit 是一個 Java 編程語言的單元測試框架。JUnit 在測試驅(qū)動的開發(fā)方面有很重要的發(fā)展,是起源于 JUnit 的一個統(tǒng)稱為 xUnit 的單元測試框架之一
Junit?常用注解:
? ??????????@Test:表示方法是測試方法
????????????@ParameterizedTest :表示方法是參數(shù)化測試?
? ??????????@RepeatedTest :表示方法可重復(fù)執(zhí)行
? ??????????@DisplayName :為測試類或者測試方法設(shè)置展示名稱
? ??????????@BeforeEach :表示在每個單元測試之前執(zhí)行
? ??????????@AfterEach :表示在每個單元測試之后執(zhí)行
? ??????????@BeforeAll :表示在所有單元測試之前執(zhí)行
? ??????????@AfterAll :表示在所有單元測試之后執(zhí)行
? ??????????@Tag :表示單元測試類別,類似于JUnit4中的@Categories
? ??????????@Disabled :表示測試類或測試方法不執(zhí)行,類似于JUnit4中的@Ignore
? ??????????@Timeout :表示測試方法運行如果超過了指定時間將會返回錯誤
? ??????????@ExtendWith :為測試類或測試方法提供擴(kuò)展類引用
Junit5 新的特性
? ? ? ? 1)異常斷言 :Assertions.assertThrows()?
? ??? ??2)超時斷言:Assertions.assertTimeout()
? ??????3)重復(fù)測試:@RepeatedTest注解,允許某個單元測試執(zhí)行多次
? ??????4)?動態(tài)測試:允許動態(tài)的創(chuàng)建單元測試,通過@TestFactory注解,會在運行時生成單元測試
? ??????5)?參數(shù)化測試:利用@ValueSource等注解,指定入?yún)?,我們將可以使用不同的參?shù)進(jìn)行多次單元測試,而不需要每新增一個參數(shù)就新增一個單元測試,省去了很多冗余代碼。
? ??????????????@ValueSource: 為參數(shù)化測試指定入?yún)碓矗С职舜蠡A(chǔ)類以及String類型,Class類型
? ??????????????@NullSource: 表示為參數(shù)化測試提供一個null的入?yún)?/p>
? ??????????????@EnumSource: 表示為參數(shù)化測試提供一個枚舉入?yún)?/p>
? ??????????????@CsvFileSource:表示讀取指定CSV文件內(nèi)容作為參數(shù)化測試入?yún)?/p>
? ??????????????@MethodSource:表示讀取指定方法的返回值作為參數(shù)化測試入?yún)?/p>
Junit 使用案例
? ??1)引入Junit 包,修改項目pom文件?

? ??2)編寫單元測試方法

? ? 3)執(zhí)行測試??

PowerMockito?單元測試
????????PowerMockito是一個擴(kuò)展了其它如EasyMock等mock框架的、功能更加強(qiáng)大的框架。PowerMockito 使用一個自定義類加載器和字節(jié)碼操作來模擬靜態(tài)方法、構(gòu)造方法、final類和方法、私有方法、去除靜態(tài)初始化器等等
PowerMockito 常用注解:? ? ? ? ? ??
????????@RunWith(PowerMockRunner.class)?使用PowerMockRunner進(jìn)行測試
? ??????@PrepareForTest({ExtensionLoader.class,Configs.class})???靜態(tài)類,測試類本身(需要mock構(gòu)造方法時)
? ??????@PowerMockIgnore("javax.management.*")?為了解決使用powermock后,提示classloader錯誤
Mock常用注解:
??????????@Mock: 創(chuàng)建一個Mock.? ? ? ??
????????????@InjectMocks: 創(chuàng)建一個實例,簡單的說是這個Mock可以調(diào)用真實代碼的方法,其余用@Mock(或@Spy)注解創(chuàng)建的mock將被注入到用該實例中。?
PowerMockito使用案例
? ??1)引入PowerMockito包,修改項目pom文件

? ??2)使用示例
? ? ? ? ? ? (a): 普通Mock: Mock參數(shù)傳遞的對象

? ??????????Powermockito.mock():主要是通過class創(chuàng)建對應(yīng)的mock對象,不同于easymock等使用proxy(代理)的方式創(chuàng)建,而是在運行過程中動態(tài)修改class字節(jié)碼文件的形式來創(chuàng)建。

????????????????Do..when..then:可以理解為,就是在什么時候,做了什么事,然后怎么樣了。
????????????????Verify:可以理解為驗證無返回值時候,查看是否被調(diào)用。對于無返回值類型的測試,只能驗證其是否被調(diào)用
? ??????????(b):?Mock方法內(nèi)部new出來的對象

? ? ? ?PowerMockito.whenNew(StudentDao.class).withNoArguments().thenReturn(studentDao);//構(gòu)建無參對象
? ??????當(dāng)使用PowerMockito.whenNew方法時,必須加注解@PrepareForTest和@RunWith。注解@PrepareForTest里寫的類是需要mock的new對象【mock -?final方法/類同理】代碼所在的類。

? ? ? ? ? ? ????@PrepareForTest(StudentFinalDao.class) 中的類為 final類 或final方法所在的類
? ???????????(c):?Mock普通類的靜態(tài)方法


????????????(e):?Mock系統(tǒng)類的靜態(tài)和final方法

????????????(f):?模擬THREAD.SLEEP()時拋出中斷異常的場景


PowerMock簡單實現(xiàn)原理
? ? ? ?? ?當(dāng)某個測試方法被注解@PrepareForTest標(biāo)注以后,在運行測試用例時,會創(chuàng)建一個新的org.powermock.core.classloader.MockClassLoader實例,然后加載該測試用例使用到的類(系統(tǒng)類除外)。
? ? ?? ? ? PowerMock會根據(jù)你的mock要求,去修改寫在注解@PrepareForTest里的class文件(當(dāng)前測試類會自動加入注解中),以滿足特殊的mock需求。例如:去除final方法的final標(biāo)識,在靜態(tài)方法的最前面加入自己的虛擬實現(xiàn)等。
? ? ? ?? ? 如果需要mock的是系統(tǒng)類的final方法和靜態(tài)方法,PowerMock不會直接修改系統(tǒng)類的class文件,而是修改調(diào)用系統(tǒng)類的class文件,以滿足mock需求。
? ?3)Mock 異常
? ??????a. mock 異常的發(fā)生
? ? ? ? ? ? ????Mockito.when(Mockito.anyObject()) .thenThrow(new Exception());
????????????????Mockito.when(Mockito.anyObject()) .thenThrow(Exception.class);
? ? ? ? b.對待無返回值的方法
????????????????使用PowerMockito.doThrow()方法.doThrow放的是需要模擬的異常,when()放的是產(chǎn)生異常的對象,括號外面寫對象調(diào)用的方法
????????????????PowerMockito.doThrow(IllegalStateException.class) .when(dictMock) ....;
?c. toThrow mock異常對象
