2015-07-10 43 views
1

例如,在verifySthIsSetCorrectly()的下面的代碼中,我應該使用assertEquals()來檢查結果還是應該拋出異常,以便它被調用者的try...catch捕獲並讓調用者處理?在JUnit中,我應該何時使用assertEquals()何時應該使用try ... catch來驗證結果?

@Parameters 
public static Collection<object[]> methodParams() { 
    List<Object[]> params = new ArrayList<Object[]>(); 
    /* arg, errorString */ 
    params.add(new Object[] {"arg1", null /*errorString*/}); 
    params.add(new Object[] {"arg2", ERROR_STRING1 /*errorString*/}); 
} 
@Test 
public void sampleTest() { 
    try { 
     MethodAndWait(arg); 
     assertNull("expect error String" + errorString, errorString); 
    } catch (Exception ex) { 
     assertNotNull("expect error String" + errorString, errorString); 
     assertTrue(ex.getMessage().contains(errorString)); 
    } 
} 

private void MethodAndWait() { 
    call_remote_server_to_have_sth_set; 
    verifySthIsSetCorrectly(); 
} 

private void verifySthIsSetCorrectly() { 
    int sth = getSth(); 
    assertEquals(sth == "5"); 
} 
+2

的assertEquals將是錯誤的。它必須是'assertEquals(5,sth)'。 –

+0

你是對的。 – user389955

回答

4

在JUnit測試,你應該使用斷言像assertEquals()來驗證方法調用的結果或對象的狀態:

@Test 
public void addingTwoNumbersShouldWork() { 
    int result = calculator.add(5, 7); 

    assertEquals(12, result); 
    assertFalse(calculator.hasOverflow()); 
} 

這是非常罕見的使用trycatch在一個JUnit測試什麼比測試一個代碼塊拋出預期的異常其他:

@Test 
public void setColorShouldThrowNullPointerExceptionOnNullInput() { 
    try { 
    deathRay.setColor(null); 
    fail("expected NullPointerException"); 
    } catch (NullPointerException expected) { 
    assertThat(expected.getMessage(), contains("death ray color")); 
    } 
} 

你並不需要使用trycatch如果你是測試方法正好扔異常:

@Test 
public void fireDeathRay() throws DeathRayException { 
    deathRay.fire(); 
} 

在上述試驗中,如果fire()拋出一個DeathRayException(或運行時異常)的fireDeathRay測試將失敗。

在JUnit4中,使用trycatch更爲罕見,因爲you can use the ExpectedException rule to check if a call throws an expected exception

+0

明白了。所以應該使用private void verifySthIsSetCorrectly()拋出異常{},因爲目的不是測試它的預期錯誤,而是測試sampleTest()的預期錯誤() – user389955

+0

@ user389955對不起,我不明白你的測試做得足夠贊同或不同意你的評論 – NamshubWriter

1

您的測試應該是

@Test 
public void sampleTest() { 
    call_remote_server_to_have_sth_set; 
    int sth = getSth(); 
    assertEquals(5, sth); 
} 

我會推薦閱讀介紹使用JUnit測試,如果你還沒有這樣做。

+0

謝謝Stefan。 verifySthIsSetCorrectly()中的代碼不像我輸入的那樣短。這就是爲什麼我把它放在一個函數中。 – user389955

0

我會在接受我的答案後採取不尋常的步驟來添加另一個答案。以前的回答集中在總結中提出的問題,但我想專注於代碼。

我認爲你想知道該怎麼做的原因之一是因爲測試sampleTest()正在測試兩個完全不同的東西。 您的測試方法正在測試相同測試方法中的正常行爲和異常行爲。

相反,分裂出來的特殊情況下檢測到自己的測試方法。例如:

@RunWith(JUnit4.class) 
public class SampleTest { 

    @Test 
    public void methodAndWaitShouldAcceptNonNullValue() { 
    ClassUnderTest.methodAndWait("arg1") 
    } 

    @Test 
    public void methodAndWaitShouldThrowWhenGivenNullValue() { 
    try { 
     ClassUnderTest.methodAndWait(null); 
     fail("NullPointerException was not thrown"); 
    } catch (NullPointerException ex) { 
     assertTrue(ex.getMessage().contains(ERROR_STRING1)); 
    } 
    } 
} 

這有幾個優點:

  1. 如果methodAndWait("arg1")拋出一個異常,測試將失敗,一個有用的堆棧跟蹤
  2. 如果methodAndWait(null)拋出比NullPointerException以外的東西,測試會帶有有用的堆棧跟蹤失敗
  3. 如果methodAndWait(null)不拋出任何東西,則測試將失敗並顯示有用的消息
  4. 兩個測試的意圖是非常明確的

如果需要使用多個參數進行測試,您可以使用Enclosed亞軍:

@RunWith(Enclosed.class) 
public class SampleTest { 

    @RunWith(Parameterized.class) 
    public static class WhenPassingNonNull { 
    @Parameters 
    public static Collection<object[]> methodParams() { 
     List<Object[]> params = new ArrayList<Object[]>(); 
     /* arg, errorString */ 
     params.add(new Object[] {"arg1", "result1"}); 
     params.add(new Object[] {"arg3", "result3"}); 
    } 

    public final String arg; 
    public final String actualResult; 

    public SampleTest(String arg, String actualResult) { 
     this.arg = arg; 
     this.actualResult = actualResult; 
    } 

    @Test 
    public void sampleTest() { 
     String actualResult = ClassUnderTest.methodAndWait(arg); 

     assertEquals(expectedResult, actualResult); 
    } 
    } 

    @RunWith(JUnit4.class) 
    public static class WhenPassingNull { 
    @Test 
    public void shouldThrowNullPointerException() { 
     try { 
     ClassUnderTest.methodAndWait(null); 
     fail(); 
     } catch (NullPointerException ex) { 
     assertTrue(ex.getMessage().contains(ERROR_STRING1)); 
     } 
    } 
    } 
} 
+0

嗨,NamshubWriter:我真正想問的問題是:我想測試sampleTest()以確保使用不同的參數(我有很多參數和相應的errorMessage來測試),我們得到相應的errorMessage正確。我不是故意測試methodAndWait(),儘管我必須在sampleTest()中調用methodAndWait()。我假設在測試sampleTest()時,methodAndWait()應該總是正常返回。但有可能methodAndWait()本身可能會捕獲異常。 (想想用createTable()替換methodAndWait()我們 – user389955

+0

想運行一些關於表的測試,我們首先調用createTable()來使表準備好,但createTable()可能會拋出一個異常,因爲表沒有被創建成功)在這種情況下,我應該讓測試失敗還是應該將失敗傳遞給sampleTest()並讓sampleTest()匹配參數errorMassage列表並決定要做什麼? – user389955

+0

我不會使用Enclose.class,因爲它需要將所有內容都更改爲靜態 – user389955

相關問題