簡體   English   中英

當我使用 try 和 catch 塊時,Junit 測試失敗。 為什么?

[英]Junit test fails when I use try and catch block. Why?

我想使用 Junit 測試框架測試我的 java 代碼。 在我的源代碼中,我使用 try 和 catch 塊來處理異常。 在我的測試方法中,我想測試這個方法。 如果我的源代碼返回一些異常並且它在我的測試方法中匹配,我的測試將通過否則失敗。 但是我的代碼沒有通過這個測試。

我找到了一種方法來解決它,但我想使用 try 和 catch 塊。 我也會分享它。

不工作我的源代碼(我想測試這個方法)

    public boolean isCreateAccount(String amount) {
    
    try { 
        
        Double balance = Double.parseDouble(amount);
        
        if(balance < 0)
             throw new Exception();

    
    } catch (Exception e) { 
        System.out.println("WARNING: Invalid amount!");
    } 
    
         return false;
    
    }

這是我在 JUnit 中的測試方法

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void testCreateAccountInvalidAmount() {

    expectedException.expect(Exception.class);
    accountServices.isCreateAccount("-100");    
    
}

工作這種方式有效,但我想使用 try 和 catch 塊我的源代碼(我想測試這個方法)

    public void isCreateCheckingAccount(String amount) {
            
        Double balance = Double.parseDouble(amount); 

        if(balance < 0)
             throw new Exception();

    
     }

這是我在 JUnit 中的測試方法

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void testCreateAccountInvalidAmount() {

    expectedException.expect(Exception.class);
    accountServices.isCreateAccount("-100");    
    
}

看你的方法了。 它有以下行為:

  • 如果金額為負數或不是數字,它會向 sysout 打印一些內容(這很糟糕;您不應該混合這樣的職責;您的 Account 工具肯定不是您的 UI 層,但這是次要問題)。 否則它什么也不打印。

  • 然后,無論您傳入什么,它都會打印 false。

因此,此方法的可觀察行為是它返回 false,並且它會向 sysout 打印一些內容。

測試它返回 false 是微不足道的。 assertFalse(services.isCreateAccount("100")會這樣做(不過,大概,您的方法總是返回 false 的事實實際上是一個錯誤)。

測試它向 sysout 打印一些東西很復雜。 那是因為你不應該在那里打印任何東西的基本問題。 如果輸出是重點的一部分,那么不是打印到System.out ,而是將一些輸出抽象(可能是java.io.PrintWriter )傳遞給AccountServices以便您可以將其變體作為測試的一部分; 一個可以配置為檢查某些預期輸出是否出現在這里的變體。

你似乎覺得這個方法會拋出一些東西。 它沒有 - 它捕獲了一些東西。 在junit 中,說:“我希望這個異常”意味着您希望它脫離方法,即相反:該方法沒有捕獲那個,或者甚至,該方法顯式拋出那個。

這將執行您想要的操作:

public boolean isCreateAccount(String amount) throws Exception {

    Double balance = Double.parseDouble(amount);

    if (balance < 0) {
        System.out.println("WARNING: Invalid amount!");
        throw new Exception();
    }

    return false;
}

雖然返回 false 沒有多大意義。

如果你真的想要那個 try catch 塊:

public boolean isCreateAccount(String amount) throws Exception {

    try {
        Double balance = Double.parseDouble(amount);
        if (balance < 0) {
            System.out.println("WARNING: Invalid amount!");
            throw new Exception();
        }
    } catch (Exception e) {
        throw e;
    }

    return false;
}

這些基本測試適用於兩個版本:

public class AccountTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void testCreateAccountInvalidAmount() throws Exception {
        Account accountServices = new Account();
        expectedException.expect(Exception.class);
        accountServices.isCreateAccount("-100");
    }

    @Test
    public void testCreateAccountZeroAmount() throws Exception {
        Account accountServices = new Account();
        assertFalse(accountServices.isCreateAccount("0"));
    }

    @Test
    public void testCreateAccountValidAmount() throws Exception {
        Account accountServices = new Account();
        assertFalse(accountServices.isCreateAccount("1"));
    }
}

我想通了這個問題。 謝謝你們的幫助。 我在這里分享我的解決方案。 如果您遇到此類問題,我希望它會有所幫助。

// 這段代碼在我的服務層...

@Override
public boolean isCreateAccount(String amount) {
    
    try { 
            
        isValidAmount(amount);
        double balance = Double.parseDouble(amount);    
        createAccount(balance);
        return true;
        
    } catch(NullPointerException e) {
        log.warn("WARNING: Empty Amount!");
        System.out.println("\nWARNING: Empty Amount!");
        
    } catch (NumberFormatException e) { 
        log.warn("WARNING: Invalid amount!");
        System.out.println("\nWARNING: Invalid amount!");
        
    } catch (NegativeAmountException e) {
        log.warn("WARNING: Amount must have a positive number!");       
        System.out.println("\nWARNING: Amount must have a positive number!");
        
    } catch (InsufficientAmountException e) {
        log.warn("WARNING: Not enough money to open a checking account!");
        System.out.println("\nWARNING: Not enough money to open a checking 
    account!");
    }
    
    return false;
}

// 這段代碼在我的服務層...

@Override
public void isValidAmount(String money) {
    
    if(money == null || money.length() == 0) {
        throw new NullPointerException("Empty Amount");
    }
    
    double amount = 0.0D;
    
    try {
        amount = Double.parseDouble(money);         
    } catch (NumberFormatException e) {
        throw new NumberFormatException("Invalid Amount");
    } 
        
    if(amount < 0.0D) {
        throw new NegativeAmountException("Negative Amount");
    }       
    
    if(amount < 25.0D) {
        throw new InsufficientAmountException("Insufficient Amount");
    }

}

//這段代碼在我的 Junit 測試類中

@Test
public void testCreateCheckingAccountNullAmount() {
    expectedException.expect(NullPointerException.class);
    expectedException.expectMessage("Empty Amount");
    accountServices.isValidAmount("");              
}

@Test
public void testCreateCheckingAccountInvalidAmount() {
    
    expectedException.expect(NumberFormatException.class);
    expectedException.expectMessage("Invalid Amount");
    accountServices.isValidAmount("a100");          
}

@Test
public void testCreateCheckingAccountNegativeAmount() {
    expectedException.expect(NegativeAmountException.class);
    expectedException.expectMessage("Negative Amount");
    accountServices.isValidAmount("-10");
}

@Test
public void testCreateCheckingAccountInsufficientAmount() {
    expectedException.expect(InsufficientAmountException.class);
    expectedException.expectMessage("Insufficient Amount");
    accountServices.isValidAmount("10");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM