2016-05-22 73 views
0

JUnit 4.12如何測試@Before方法?

我正在爲類方法編寫一個測試。這裏是如何看起來像

public interface MyInterface{ 
    //method declaration 
} 

public class MyClass implements MyInterface{ 

    private int a; 
    private in b; 

    public MyClass(int a, int b){ 
     if(a <= b + 5) 
      throw new IllegalArgumentException("Invalid arguments"); 
     this.a = a; 
     this.b = b; 
    } 

    //methods 
} 

現在我想測試這個類:

public class MyClassTest{ 
    private static final int THRESHOLD = 1000; 

    private MyClass mc; 

    @Before 
    public void init(){ 
     Random rnd = new Random(); 
     int a = rnd.nexInt(THRESHOLD), 
      b = rnd.nexInt(THRESHOLD); 
     mc = new MyClass(a, b); 
    } 
} 

但在這種情況下,init()可能會拋出異常。所以我想測試保持不變式以及初始化一個對象以測試其他方法。

如何在JUnit中正確執行此操作?

+4

該單元測試的設計不正確。你通常會有3個測試用例,它們的固定值是'a'和'b'。我們測試一下'a'低於'b + 5'的情況,一個測試'a'等於'b + 5'的情況,最後一個測試'a'大於'b + 5'的情況。使用'隨機'在這裏沒有必要或有幫助。 – Tom

+0

爲什麼在@之前呢?如果你想測試異常,只是一個測試。 – RobAu

+1

在大多數情況下,測試時使用隨機/非確定性值是一個壞主意。即使在應該以某種隨機方式行事的課堂中,測試也通常被設計爲使得他們的行爲以某種方式變得可預測。 –

回答

0

@Before旨在初始化您需要測試的任何內容。如果你想檢查任何東西 - @Test方法是顯而易見的地方。

就你而言,我認爲你應該創建幾個單獨的測試方法,明確地傳遞有效和無效的參數。這樣,如果測試失敗,你知道它爲什麼發生,如果它沒有失敗 - 你可以確定這個邏輯是正確的。 如果你使用隨機,你不能確定:也許被測試的代碼仍然是正確的或隨機值只是適合,你是幸運的。

0

您需要兩個測試類。

第一個用於測試構造函數的行爲。其次爲測試方法的行爲。 另外,我會假設每個測試過的方法都需要在@before中定義的代碼。

因此,我們有:

public interface MyInterface{ 
    //method declaration 
} 

public class MyClass implements MyInterface{ 

private int a; 
private in b; 

public MyClass(int a, int b){ 
    if (a <= b + 5) { 
     throw new IllegalArgumentException("Invalid arguments"); 
    } 
    this.a = a; 
    this.b = b; 
} 

//methods 
} 

現在我們爲構造

public class MyClassConstructorTest{ 
private static final int THRESHOLD = 1000; 

@Test 
public void allArgsConstructor_okValues_shouldCreateObjectOK(){ 
    // Given 
    int a = 0; 
    int b = a - 5; 
    // tested method 
    new MyClass(a, b); 
    // then no exception (test: ok) 
} 


@Test(expected = IllegalArgumentException.class) 
public void allArgsConstructor_aLesserBplus5_shouldThrowException(){ 
    // Given 
    int a = 0; 
    int b = a; 

    // tested method 
    new MyClass(a, b); 
    // then fail constructor assertion 
    // see expected annotation 
} 

// other tests for constructor you need? 

} 

創建測試之後,你創建你的正常測試:

public class MyClassTest{ 
private static final int THRESHOLD = 1000; 

private MyClass mc; 

@Before 
public void init(){ 
    int a = 0; 
    int b = a+5; 
    mc = new MyClass(a, b); 
} 

// normal test that use @before 
} 

PS:還指出在意見:從不在測試中隨機使用。

PS2:「如何測試構造方法」

0

我覺得你的問題,使用隨機數的開始:如果你可以,但你應該你的問題重命名爲不確定。如果您在單元測試中使用隨機數字,您必須確保您所覆蓋的範圍適合一種情況並且只有一種情況。你的情況,你實際上有三種情況:

  1. 一個< B + 5 - 產生的異常(順便說一句,這是很好的做法,始終使用讚譽:{})。
  2. a> b + 5 - 這是有效的情況。
  3. A = B + 5 - 這是另一種無效的情況下

您需要測試的三種情況,所以你需要爲每個案件的設置。您正在運行的問題是,您正試圖將所有案例合併爲一個。這種測試在單元測試中非常令人沮喪,因爲您正在引入一個可變代碼組件,並且您所說的需要進行測試。作爲一個建議,做3個變量b1和b2和b3

說a是一個隨機數。使b1 = a - 5 - 1和b2 = a - 5 + 1和b3 = a - 5。然後爲每種情況提供3種測試方法。我建議您使用覆蓋率工具,例如MoreUnit,因爲它確保您可以更輕鬆地檢測到實際需要測試的所有不同情況。