拋出問題
在實驗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