junit測試:異常測試

拋出問題

在實驗4中需要我們對異常的處理進行測試:考慮 3.1 節中出現的多種非法情形,設計一組測試用例,人爲製造非法輸入的文件和非法輸入的圖操作指令,對程序進行健壯性和正確性測試,想方設法讓程序崩潰(即驗證程序是否有容錯能力)。
問題來了,我們應該怎樣對異常進行測試?

測試異常的方法

1.@Test(expected…)

@Test註解有一個可選的參數,”expected”允許你設置一個Throwable的子類。如果你想要驗證上面的canVote()方法拋出預期的異常,我們可以這樣寫:

@Test(expected = GrammarException.class)
    public void test_vertex_args() throws GrammarException, VertexNotExistException, MismatchException, WeightException, LabelException {        
        GraphPoet g = (GraphPoet) new GraphPoetFactory().creatGraph("test/file/GraphPoet_vertex_args.txt");      
    }

簡單明瞭,這個測試有一點誤差,因爲異常會在方法的某個位置被拋出,但不一定在特定的某行。同時沒有辦法檢查拋出異常的信息。

2.ExpectedException

如果要使用JUnit框架中的ExpectedException類,需要聲明ExpectedException異常。

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

然後你可以使用更加簡單的方式驗證預期的異常。並且可以設置預期異常的屬性信息。

@Test
    public void test_vertex_args() throws GrammarException, VertexNotExistException, MismatchException, WeightException, LabelException {        
        thrown.expect(GrammarException.class);
        thrown.expectMessage("The vertex args is lack.");
        GraphPoet g = (GraphPoet) new GraphPoetFactory().creatGraph("test/file/GraphPoet_vertex_args.txt");      
    }

除了可以設置異常的屬性信息之外,這種方法還有一個優點,它可以更加精確的找到異常拋出的位置。
另一種書寫方式:

thrown.expect(IllegalArgumentException.class, “age should be +ve”);

3.Try/catch with assert/fail

在JUnit4之前的版本中,使用try/catch語句塊檢查異常

@Test
    public void test_vertex_args() throws GrammarException, VertexNotExistException, MismatchException, WeightException, LabelException {        
        try {
        GraphPoetFactory().creatGraph("test/file/GraphPoet_vertex_args.txt");   
    } catch (GrammarException ex) {
        assertThat(ex.getMessage(), containsString("The vertex args is lack."));
    }
    fail("expected for GrammarException of The vertex args is lack.");
    }

儘管這種方式很老了,不過還是非常有效的。主要的缺點就是很容易忘記在catch語句塊之後需要寫fail()方法,如果預期異常沒有拋出就會導致信息的誤報。我曾經就犯過這樣的錯誤。

測試IOException

在IOException中,我們對如果沒有找到對應文件,將會要求用戶輸入一個新的文件,並且重新進行文件的讀取。

try{

}catch (IOException e) {
            logger.warn(e.getClass().getName() + ":" + e.getMessage());
            System.out.println("Please input a new file:");
            Scanner in = new Scanner(System.in);
            String newFilePath = in.nextLine();
            g = (GraphPoet) new GraphPoetFactory().creatGraph(newFilePath);
        }

在測試的時候,我們需要模擬用戶輸入一個正確的文件名稱,這時需要用到IO流的內容的知識。

@Test
    public void test_io() throws GrammarException, VertexNotExistException, MismatchException, WeightException, LabelException , OtherPropertyException{        
        GraphPoetFactory  factory = new GraphPoetFactory();
        String string = "test/file/GraphPoet.txt\r\n";
        InputStream stdin = System.in;        
        System.setIn(new ByteArrayInputStream(string.getBytes()));
        factory.creatGraph("test/file/GraphPoet_3333.txt");  
        System.setIn(stdin);              
    }

其中的string爲正確的輸入文件的地址的內容,我們新建一個輸入流,將字符串的內容傳入輸入流,最後在進行時會拋出IOException,並且要求輸入新的文件地址,如果沒有拋出異常,那麼就會運行失敗。

參考文獻

使用JUnit測試預期異常
https://blog.csdn.net/tayanxunhua/article/details/20570457

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章