Junit5系列-Junit5中assertThrows()與assertDoesNotThrow()方法詳解
系列導航
簡介
Junit5中新新增了對方法丟擲異常的斷言Assertions類中的assertThrows()和assertDoesNotThrow(),使用此方法可以對被測試方法丟擲的異常進行斷言測試,而在junit4中的對異常進行斷言實現相對來說比較麻煩的。
- assertThrows()主要對被測試方法的丟擲異常進行測試,測試所丟擲的異常是否滿足預期。
- assertDoesNotThrow()主要用來判定被測試方法是否丟擲了異常,如果丟擲異常則斷言失敗,無異常丟擲則斷言成功。
下面來看一些案例使用:
案例分析
其中每個方法的作用程式碼中的註釋寫的已經非常清楚了
,就不再贅述了.
大家最好將程式碼自己測試一遍,可以加深理解與記憶!
案例程式碼:
1.使用到的被測試方法
public class AssertTestModel {
public static void testThrowArithmeticException(int numA,int numB){
try {
int result = numA/numB;
}catch (ArithmeticException e){
throw new ArithmeticException("The numB not allowed to '0'!!");
}
}
}
2.測試案例
import cn.yoylee.junit5.AssertTestModel;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author liyangyang
* @date 2019/1/14
*/
class AssertThrowsTest {
@Test
void testAssertThrows(){
//2:如果丟擲的異常與設定的異常相同,則這一步的斷言成功並返回一個異常的頂級父類
Throwable exception = assertThrows(ArithmeticException.class,()->{
//1:執行此語句會丟擲一個ArithmeticException異常,被assertThrows方法捕獲
AssertTestModel.testThrowArithmeticException(2,0);
});
//3:接下來便可以對返回的異常進行一些其他的測試
//比如對異常的資訊進行斷言測試等。。
assertEquals("The numB not allowed to '0'!!",exception.getMessage());
}
@Test
void testAssertDoesNotThrow1(){
//因為函數語言程式設計中的執行語句丟擲了異常,所以斷言失敗
assertDoesNotThrow(()->{
AssertTestModel.testThrowArithmeticException(2,0);
});
}
@Test
void testAssertDoesNotThrow2(){
//斷言成功
assertDoesNotThrow(()->{
AssertTestModel.testThrowArithmeticException(2,1);
});
}
@Test
void testtestAssertDoesSNotThrowHaveReturn(){
//這是帶返回引數的assertDoesNotThrow方法,在沒有異常丟擲的情況下會返回一個值
int re = assertDoesNotThrow(() -> {
int result = AssertTestModel.testThrowArithmeticException(2,1);
return result;
});
//其實上面的語句可以簡化為下面的語句不過為了便於理解,還是使用的上述表達
// int re = assertDoesNotThrow(() -> AssertTestModel.testThrowArithmeticException(2,1));
//可以對返回的結果值進行一些測試等
assertEquals(re,2);
}
}
到這裡大家應該已經知道如何使用這兩個方法了,但是其執行過程是怎樣的,怎樣設計的呢?我們接下來看一下
原始碼分析
首先,assertThrows有三個過載方法:
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable) {
return AssertThrows.assertThrows(expectedType, executable);
}
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, String message) {
return AssertThrows.assertThrows(expectedType, executable, message);
}
public static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, Supplier<String> messageSupplier) {
return AssertThrows.assertThrows(expectedType, executable, messageSupplier);
}
我們可以看到,其中都是呼叫了AssertThrows.assertThrows
方法,這裡的AssertThrows和Assertions的關係和我們在Junit5系列-Junit5中Assertions斷言類一文中Assertions和assertTrue關係一樣。
接下來就看一下AssertThrows.assertThrows()
到底是何許人也:
private static <T extends Throwable> T assertThrows(Class<T> expectedType, Executable executable, Object messageOrSupplier) {
try {
//執行引數executable中設定的語句
executable.execute();
} catch (Throwable var5) {
//判斷捕獲的異常是否和自定義的異常類相同,相同則返回異常物件
if (expectedType.isInstance(var5)) {
return var5;
}
//如果捕獲的異常和自定義的異常不同,通過自定義的列印資訊messageOrSupplier組裝異常並丟擲(AssertionFailedError為Junit5的自定義異常)
String message = AssertionUtils.buildPrefix(AssertionUtils.nullSafeGet(messageOrSupplier)) + AssertionUtils.format(expectedType, var5.getClass(), "Unexpected exception type thrown");
throw new AssertionFailedError(message, var5);
}
//如果執行的語句沒有異常,組裝“沒有異常的”異常丟擲
String message = AssertionUtils.buildPrefix(AssertionUtils.nullSafeGet(messageOrSupplier)) + String.format("Expected %s to be thrown, but nothing was thrown.", AssertionUtils.getCanonicalName(expectedType));
throw new AssertionFailedError(message);
}
我在原始碼中註釋了其執行過程,相對來說是比較簡單的,這裡的引數引數介紹一下:
- 返回型別:
<T extends Throwable>
,繼承自Throwable類的子型別,必須是繼承Throwable的子類。所以我們在測試方法中可以直接使用Throwable接受返回值。 - 引數:
Class<T> expectedType
,定義想要測試的異常型別 - 引數:
Object messageOrSupplier
,這裡Object型別的原因是可能會接受String型別的自定義資訊型別,還有可能接受函式式介面Supplier的自定義資訊。 - 引數:
Executable executable
,函式式介面,可以使用lambda表示式,可以稍微看一下其原始碼:
@FunctionalInterface
@API(
status = Status.STABLE,
since = "5.0"
)
public interface Executable {
void execute() throws Throwable;
}
其中@FunctionalInterface
可以看出是一個函式式介面,無參無返回值的呼叫方法。
好了,到這裡大家應該對assertThrows方法有個全面的瞭解,對於的assertDoseNotThrows方法來說,實現方式類似,有6個過載方法,3個有返回值的3個無返回值的過載, 最後都是呼叫的AssertDoesNotThrow.assertDoesNotThrow()方法實現的,其原始碼為:
//泛型返回值
private static <T> T assertDoesNotThrow(ThrowingSupplier<T> supplier, Object messageOrSupplier) {
try {
//函式式介面方法執行,無異常正常返回
return supplier.get();
} catch (Throwable var4) {
//捕獲異常則根據messageOrSupplier自定義訊息組裝異常並丟擲
String message = AssertionUtils.buildPrefix(AssertionUtils.nullSafeGet(messageOrSupplier)) + "Unexpected exception thrown: " + var4.getClass().getName();
throw new AssertionFailedError(message, var4);
}
}
如果轉載此博文,請附上本文連結,謝謝合作~ :https://blog.csdn.net/csdn___lyy
如果感覺這篇文章對您有所幫助,請點選一下“喜歡”或者“關注”博主,您的喜歡和關注將是我前進的最大動力!
相關文章
- Junit5系列-Junit5中Assertions斷言類
- Junit5系列-Junit5中Assumptions假設類
- Junit5系列-Junit5中@Disabled禁止執行
- Junit5系列-Junit5中@DisplayName自定義名稱
- Junit5系列-什麼是Junit5?
- Junit5系列-Junit5中DisabledCondition條件測試執行
- JUnit5註解學習指引
- JUnit5依賴注入與測試介面依賴注入
- JUnit5編寫基本測試
- junit5 是不是全方面吊打 testng
- JUnit5的Tag、Filter、Order、LifecycleFilter
- JUnit5學習之三:Assertions類
- JUnit5學習之一:基本操作
- JUnit5學習之二:Assumptions類
- JUnit5學習之五:標籤(Tag)和自定義註解
- 基於 junit5 實現 junitperf 原始碼分析原始碼
- JUnit5學習之四:按條件執行
- JUnit5學習之八:綜合進階(終篇)
- Java新一代單元測試框架JUnit5速覽Java框架
- Springboot整合JUnit5優雅進行單元測試Spring Boot
- Spring 對 Junit4,Junit5 的支援上的運用Spring
- JUnit5的條件測試、巢狀測試、重複測試巢狀
- JUnit5學習之六:引數化測試(Parameterized Tests)基礎Zed
- JUnit5學習之七:引數化測試(Parameterized Tests)進階Zed
- Pandas中resample方法詳解
- pandas | 詳解DataFrame中的apply與applymap方法APP
- Selenium系列教程-05 findElements 方法詳解
- C#中抽象方法與虛方法的區別詳解及示例C#抽象
- Java中getGenericSuperclass()方法詳解Java
- Java中的main()方法詳解JavaAI
- Java中的方法引用詳解Java
- Redis系列之key操作命令與Redis中的事務詳解(六)Redis
- Vue入門—事件與方法詳解Vue事件
- JQuery中$.ajax()方法引數詳解jQuery
- list中add、set方法詳解
- php中Session使用方法詳解PHPSession
- Android中的onWindowFocusChanged()方法詳解Android
- @Transactional詳解(作用、失效場景與解決方法)