国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Junit 單元測試之錯誤和異常處理

這篇具有很好參考價值的文章主要介紹了Junit 單元測試之錯誤和異常處理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

錯誤和異常處理是測試中非常重要的部分。假設(shè)我們有一個服務(wù),該服務(wù)從數(shù)據(jù)庫中獲取用戶?,F(xiàn)在,我們要考慮的錯誤場景是:數(shù)據(jù)庫連接斷開。

整體代碼示例

首先,為了簡化,我們讓服務(wù)層就是簡單的類,然后使用Id查找用戶,這個和之前測試UserService接口不太一樣哦:

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public User getUserById(Long id) {
        return userRepository.findById(id).orElse(null);
    }
}

現(xiàn)在,我們要模擬UserRepository的行為,使其在嘗試獲取用戶時引發(fā)一個異常。這里我們使用Mockito進行模擬:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

//之前我們是定義了一個UserService接口,現(xiàn)在簡化成UserService類了哈
    @InjectMocks
    private UserService userService;

    @Mock
    private UserRepository userRepository;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

//重點,后文詳解!
    @Test(expected = DatabaseConnectionException.class)
    public void testGetUserByIdWithDbError() {
        when(userRepository.findById(anyLong())).thenThrow(new DatabaseConnectionException("Database connection failed!"));

        userService.getUserById(1L);
    }
}

//重點,后文詳解!
class DatabaseConnectionException extends RuntimeException {
    public DatabaseConnectionException(String message) {
        super(message);
    }
}

在上述測試中,我們模擬了userRepository.findById()方法,使其拋出DatabaseConnectionException異常。然后,我們在測試方法上使用@Test(expected = DatabaseConnectionException.class)來表示我們期望該方法引發(fā)此異常。

這樣,如果getUserById方法在遇到此異常時沒有正確處理,測試將失敗。這確保了即使在面對意外的數(shù)據(jù)庫問題時,我們的代碼仍能按預(yù)期的方式運行(在這種情況下,按預(yù)期拋出異常)。


到底在模擬什么?到底在測試什么?

下面,我們進一步說明:

  1. 測試目標:這個測試的目標是確保當userRepository.findById()方法拋出DatabaseConnectionException異常時,userService.getUserById()方法也會拋出同樣的異常。

  2. 模擬異常:在這行代碼中,我們指定了當userRepository.findById()被調(diào)用時,它應(yīng)該拋出DatabaseConnectionException異常。

    when(userRepository.findById(anyLong())).thenThrow(new DatabaseConnectionException("Database connection failed!"));
    
  3. 調(diào)用Service方法:接下來,我們調(diào)用了userService.getUserById(1L)。我們期望它在內(nèi)部調(diào)用userRepository.findById()(這在實際的UserService實現(xiàn)中應(yīng)該是這樣的)。因此,由于我們已經(jīng)模擬了userRepository.findById()來拋出異常,所以userService.getUserById()也應(yīng)該會拋出這個異常。

  4. 驗證異常@Test(expected = DatabaseConnectionException.class)注解表示我們期望這個測試方法在執(zhí)行時會拋出DatabaseConnectionException異常。如果這個方法執(zhí)行完并沒有拋出這個異常,那么測試將會失敗。

  5. 測試的目的:這個測試的目的并不是檢查userRepository.findById()本身是否真的會拋出異常,而是檢查當它拋出異常時,userService.getUserById()是否會正確地傳遞這個異常。這可以幫助我們確保UserService在處理異常時的行為是正確的。其實本質(zhì)上來說,拋出異常和預(yù)期值的測試邏輯幾乎是一樣的,都是通過給定下層值,驗證上層代碼關(guān)系。

綜上所述,這個測試確保了當?shù)讓?code>UserRepository出現(xiàn)數(shù)據(jù)庫連接錯誤時,上層的UserService可以正確地傳遞這個錯誤。這對于后續(xù)的異常處理很重要,例如:在Controller層將這個異常轉(zhuǎn)化為一個友好的錯誤消息返回給用戶。


什么時候測試失?。?/h2>

在正常情況下,只要Service層確實調(diào)用了Repository的方法,并且Repository的方法拋出了RuntimeException(或其子類),那么Service層的調(diào)用方法也應(yīng)該會收到并進一步拋出這個異常。

但是,以下幾種情況可能導(dǎo)致測試不通過:

  1. 異常被吞沒:如果Service層調(diào)用了Repository的方法,但內(nèi)部捕獲了該異常并沒有重新拋出,那么測試就會失敗。例如:

    public User getUserById(Long id) {
        try {
            return userRepository.findById(id);
        } catch (DatabaseConnectionException e) {
            // 異常被吞沒了
            return null;
        }
    }
    
  2. 調(diào)用的方法不正確:如果Service層沒有調(diào)用預(yù)期的Repository方法,而是調(diào)用了其他方法,或者完全沒有調(diào)用,那么模擬的異常就不會被觸發(fā),導(dǎo)致測試失敗。

  3. 模擬的不正確:如果在測試中模擬的方法或參數(shù)與實際調(diào)用的方法或參數(shù)不匹配,那么模擬的異常也不會被觸發(fā)。例如,如果Service實際上是這樣調(diào)用的:userRepository.findById(2L),但我們的模擬是這樣的:when(userRepository.findById(1L))...,那么異常就不會被觸發(fā)。

    • 其他未預(yù)料到的異常:有時可能會有其他的未被預(yù)料到的異常被拋出,這也會導(dǎo)致測試失敗。

因此,雖然大多數(shù)情況下,如果Repository層方法拋出了異常,Service層應(yīng)該也會拋出,但還是存在一些情況導(dǎo)致測試不通過,這也是進行此類測試的原因。


Exception 異常類定義

class DatabaseConnectionException extends RuntimeException {
    public DatabaseConnectionException(String message) {
        super(message);
    }
}

DatabaseConnectionException是一個自定義的異常類。在Java中,異常是用來表示程序運行中的問題或異常情況的對象。當某些問題發(fā)生時,通常會拋出(throw)一個異常。

這里,我們定義了一個繼承自RuntimeException的新異常類DatabaseConnectionException。RuntimeException是Java中所有非檢查型異常的基類。所謂“非檢查型”是指編譯器不強制我們捕獲或聲明它。這與Exception(檢查型異常)相對。

關(guān)于DatabaseConnectionException類的解釋:

  1. class DatabaseConnectionException extends RuntimeException - 這表示我們正在定義一個名為DatabaseConnectionException的新類,該類是RuntimeException的子類。這意味著DatabaseConnectionException繼承了RuntimeException的所有特性。

  2. public DatabaseConnectionException(String message) - 這是DatabaseConnectionException類的構(gòu)造方法。當我們創(chuàng)建DatabaseConnectionException的新實例時,可以傳遞一個消息字符串給這個構(gòu)造函數(shù)。

  3. super(message); - 這行代碼調(diào)用了父類(RuntimeException)的構(gòu)造方法,并將message傳遞給它。這樣,當異常被拋出并捕獲時,我們可以獲取并顯示這個消息。

這種自定義異常,通常在我們希望為特定的錯誤情況定義更具描述性的異常名時使用,或者當我們想為特定的異常情況添加更多上下文信息時使用,信息越多,測試反饋的效果越好,所以一般使用自定義異常,繼承RuntimeException!下面我們討論一下,為什么建議使用RuntimeException?


RuntimeException 使用意義

使用RuntimeException(非檢查型異常)還是Exception(檢查型異常)來自定義數(shù)據(jù)庫異常(或其他異常)是一個設(shè)計決策,并且這兩者在Java中有不同的含義和用途。

下面是一些選擇使用RuntimeException的原因:

  1. 不需要顯式處理:當方法中拋出非檢查型異常時,調(diào)用該方法的代碼不需要顯式地處理異常(即不需要使用try-catch或在方法簽名中使用throws)。這使得代碼更簡潔,更易讀。

  2. 表示編程錯誤:非檢查型異常通常用于表示編程錯誤,例如空指針異常、數(shù)組越界等。對于某些數(shù)據(jù)庫異常,如配置錯誤,這可能是一個編程錯誤,因此使用RuntimeException可能更合適。

  3. 強制開發(fā)者考慮異常處理策略:使用檢查型異常會強制調(diào)用者處理異常,這可能會導(dǎo)致過多的try-catch塊并使代碼復(fù)雜化。而使用非檢查型異常,開發(fā)者可以選擇在何處處理異常,這通常會導(dǎo)致更好、更集中的異常處理策略。

  4. 與現(xiàn)有框架兼容:許多現(xiàn)代Java框架,如Spring,傾向于使用非檢查型異常,因為它們認為異常應(yīng)該在應(yīng)用程序的高層(如Controller或Service)中統(tǒng)一處理。

  5. 靈活性:有時,在開發(fā)過程的后期,可能會發(fā)現(xiàn)某些異常不再是關(guān)鍵的,不需要強制處理。對于非檢查型異常,這意味著不需要修改方法簽名或調(diào)用代碼。

然而,這并不意味著總是應(yīng)該選擇非檢查型異常。有時,如果你希望調(diào)用者必須處理某個特定的異常,使用檢查型異??赡芨线m。選擇使用哪種異常是基于特定上下文和需求的決策。但在許多現(xiàn)代Java應(yīng)用程序中,傾向于使用RuntimeException因為它提供了更大的靈活性和簡潔性。


總結(jié)

模擬異常的目的

  • 驗證代碼在遇到異常時是否有正確的響應(yīng),例如是否拋出了預(yù)期的異常。
  • 確保代碼在異常情況下仍然能夠維持預(yù)期的狀態(tài)或行為。
  • 單元測試通常關(guān)注隔離性,因此模擬異常可以確保在不涉及實際外部依賴的情況下,模擬各種可能的場景。

真正的數(shù)據(jù)庫異常是不是Runtime異常

在Java中,數(shù)據(jù)庫操作可能會拋出多種異常。其中,SQLException 是一個受檢異常(checked exception)。

但在很多現(xiàn)代的框架中(如Spring),這些受檢異常通常會被轉(zhuǎn)換成運行時異常(runtime exceptions),這樣可以使代碼更為簡潔,避免了過多的try-catch塊。文章來源地址http://www.zghlxwxcb.cn/news/detail-717354.html

到了這里,關(guān)于Junit 單元測試之錯誤和異常處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Linux下安裝junit,并通過命令執(zhí)行junit單元測試

    1.首先你的Linux下應(yīng)該已經(jīng)安裝了jdk,如果沒有安裝,請先查詢安裝,并配置好環(huán)境變量 2.首先找到你的jdk安裝目錄,如果你已經(jīng)配置好環(huán)境變量的話,可以執(zhí)行下面的語句: ? 博主的安裝目錄是/usr/lib/jvm/temurin-11-jdk-amd64/ 3.下載junit-4.11.jar和hamcrest-core-1.3.jar到這個目錄里的l

    2024年02月04日
    瀏覽(16)
  • 軟件測試實驗:Junit單元測試

    軟件測試實驗:Junit單元測試

    目錄 前言 實驗?zāi)康?實驗內(nèi)容 實驗要求 實驗過程 題目一 題目一測試結(jié)果 題目二 題目二實驗結(jié)果 總結(jié) 軟件測試是軟件開發(fā)過程中不可缺少的一個環(huán)節(jié),它可以保證軟件的質(zhì)量和功能,發(fā)現(xiàn)并修復(fù)軟件的缺陷和錯誤。軟件測試分為多種類型,其中一種是單元測試,即對軟件

    2024年02月02日
    瀏覽(33)
  • 單元測試 —— JUnit 5 參數(shù)化測試

    單元測試 —— JUnit 5 參數(shù)化測試

    目錄 設(shè)置 我們的第一個參數(shù)化測試 參數(shù)來源 @ValueSource @NullSource @EmptySource @MethodSource @CsvSource @CsvFileSource @EnumSource @ArgumentsSource 參數(shù)轉(zhuǎn)換 參數(shù)聚合 獎勵 總結(jié) 如果您正在閱讀這篇文章,說明您已經(jīng)熟悉了JUnit。讓我為您概括一下JUnit——在軟件開發(fā)中,我們開發(fā)人員編寫的代

    2024年02月03日
    瀏覽(17)
  • java 單元測試Junit

    java 單元測試Junit

    所謂 單元測試 ,就是針對最小的功能單元,編寫測試代碼對其進行正確性測試。為了測試更加方便,有一些第三方的公司或者組織提供了很好用的測試框架,給開發(fā)者使用。這里介紹一種Junit測試框架。Junit是第三方公司開源出來的,用于對代碼進行單元測試的工具(IDEA已經(jīng)

    2024年02月07日
    瀏覽(37)
  • 單元測試junit+mock

    單元測試junit+mock

    單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。至于“單元”的大小或范圍,并沒有一個明確的標準,“單元”可以是一個方法、類、功能模塊或者子系統(tǒng)。 單元測試通常和白盒測試聯(lián)系到一起 ,如果單從概念上來講兩者是有區(qū)別的,不過我們通

    2024年02月08日
    瀏覽(36)
  • 使用JUnit單元測試

    使用JUnit單元測試

    前提: ? 測試題目: 根據(jù)輸入的年份和月份判斷月份的天數(shù)。若月份不在有效范圍之內(nèi),應(yīng)提示:“月份輸入不正確?!?。月份不為2月,根據(jù)輸入月份輸出對應(yīng)的月份天數(shù)。月份為2月,根據(jù)年份判斷如為普通閏年,輸出2月份正確天數(shù);如為世紀閏年,輸出2月份正確天數(shù);

    2024年02月04日
    瀏覽(22)
  • 測開 (Junit 單元測試框架)

    測開 (Junit 單元測試框架)

    目錄 了解 Junit 引入相關(guān)依賴 1、Junit注解 @Test @BeforeEach、@BeforeAll @AfterEach @AfterAll 2、斷言 1、Assertions - assertEquals 方法 2、Assertions - assertNotEquals 方法 3、Assertions - assertTrue assertFalse方法 4、Assertions - assertNull assertNotNull 小結(jié) 3、用例的執(zhí)行順序 - 方法排序( @Order 注解) 4、測試套

    2024年02月07日
    瀏覽(18)
  • 單元測試junit

    單元測試junit

    官網(wǎng):https://junit.org/ JUnit是一個Java語言的單元測試框架,Junit測試是程序員測試,即所謂白盒測試,因為程序員知道被測試的軟件如何完成功能和完成什么樣的功能,Junit是一套框架,繼承TestCase類,就可以用Junit進行自動測試了 測試方法必須使用 @Test 修飾 測試方法必須使用

    2024年02月10日
    瀏覽(18)
  • Junit單元測試(筆記)

    Junit單元測試(筆記)

    Junit是一個Java語言的單元測試框架,簡單理解為可以用于取代java的( 部分 )main方法。Junit屬于 第三方 工具,需要 導(dǎo)入jar包 后使用。 a.在當前模塊下創(chuàng)建lib文件夾 b.把junit的jar包,拷貝到lib的文件夾中 c.把jar包添加到圖書館中 執(zhí)行的結(jié)果: 備注: Junit常用注解(Junit5.x版本) @Befor

    2023年04月26日
    瀏覽(19)
  • Junit單元測試

    Junit單元測試

    JUnit 是一個 Java 編程語言的單元測試框架。JUnit 在測試驅(qū)動的開發(fā)方面有很重要的發(fā)展,是起源于 JUnit 的一個統(tǒng)稱為 xUnit 的單元測試框架之一。 單元:在Java中,一個類就是一個單元 單元測試:程序猿編寫的一小段代碼,用來對某個類中的某個方法進行功能測試或業(yè)務(wù)邏輯

    2023年04月12日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包