2013-04-06 57 views
2

我試圖單元測試從鍵盤輸入的主要方法。我知道關於測試鍵盤輸入和使用System.setIn(...)這樣做有幾個問題,但它只適用於我的第一個輸入。單元測試多個連續的鍵盤輸入

我的代碼:

public class TestApp { 
    @Test 
    public void testMain() { 
     InputStream stdin = System.in; 
     try { 
      System.setIn(new ByteArrayInputStream("s\r\nx\r\n".getBytes())); 

      String args[] = {}; 
      App.main(args); 

      // TODO: verify that the output is what I expected it to be 
     } 
     catch(IOException e) { 
      assertTrue("Unexpected exception thrown: " + e.getMessage(), false); 
     } 
     finally { 
      System.setIn(stdin); 
     } 
    } 
} 

我試圖做到的,是對輸入的',然後「X」(兩個不同的條目)。

正常使用程序時,按's'後按enter鍵輸出內容,按'x'後輸出其他內容。主要的方法是這樣的:

class App { 
    public static void main(String[] args) throws IOException { 
     int choice; 
     do { 
      choice = getChar(); 
      switch(choice) { 
       case 's': 
        System.out.println("Text for S"); 
        break; 
       case 'x': 
        System.out.println("Exiting"); 
        break; 
      } 
     } while(choice != 'x'); 
    } 

    public static String getString() throws IOException { 
     InputStreamReader isr = new InputStreamReader(System.in); 
     BufferedReader br = new BufferedReader(isr); 
     String s = br.readLine(); 
     return s; 
    } 

    public static char getChar() throws IOException { 
     String s = getString(); 
     return s.charAt(0); 
    } 
} 

注:我知道要實現它的注入的InputStream的依賴,並用它來代替System.in的最佳方式,但我不能改變的代碼。這是我的限制,我不能更改main()getString()getChar()方法。

當我執行測試,這是輸出:在

文本對於s

顯示java.lang.NullPointerException
在App.getChar(tree.java:28)
App.main(tree.java:7)
at TestApp.testMain(TestApp.java:15)< 23內部調用>

因此,它看起來像獲得第一個輸入('s'),但不是第二個...

任何幫助非常感謝。

+0

如果您甚至無法修復單元測試檢測到的錯誤和設計問題,那麼單元測試某些代碼有什麼意義? – 2013-04-06 10:57:55

+0

這是一項任務,我的任務是檢測缺陷並撰寫報告。修復錯誤不是任務的一部分,我不能更改代碼...... :( – satoshi 2013-04-06 11:07:40

+1

因此,您似乎發現了一個缺陷:代碼不容易進行單元測試。 – 2013-04-06 11:08:44

回答

1

getString方法構造上的每個呼叫,這將前readLine返回讀取System.in 8192個字符到其緩衝器中的新BufferedReader。這意味着它在第一次調用時讀取's'以及'x',但僅使用第一行。然後,從該方法返回時,BufferedReader被丟棄。在下一次調用中,它會構造一個新實例來查找剩餘字符,但由於System.in已經耗盡,因此找不到任何字符。

毫無疑問,這是一個錯誤。

一種可能的解決方法是構建一個虛擬的InputStream,在最初的's'和換行符後面加上'x'和換行符後填充爲8k。

您還可以構建更精細的模擬System.in與模擬System.out相結合,並在檢測到呼叫System.out.println時用更多輸入進行補充。