2008-10-16 74 views
7

我有一個Java方法,用ProcessBuilder啓動一個Process,並將其輸出管道輸入到一個字節數組中,然後在該過程完成時返回它的字節數組。如何對使用ProcessBuilder和Process的Java方法進行單元測試?

僞代碼:

ProcessBuilder b = new ProcessBuilder("my.exe") 
Process p = b.start(); 
... // get output from process, close process 

什麼會去了解單元測試這種方法的最佳方法是什麼?我還沒有找到一種方式來嘲笑的ProcessBuilder(它的最後),即使有令人難以置信的真棒JMockit,它給了我一個NoClassDefFoundError的:

java.lang.NoClassDefFoundError: test/MockProcessBuilder 
    at java.lang.ProcessBuilder.<init>(ProcessBuilder.java) 
    at mypackage.MyProcess.start(ReportReaderWrapperImpl.java:97) 
    at test.MyProcessTest.testStart(ReportReaderWrapperImplTest.java:28) 

有什麼想法?


回答 - 奧拉夫建議,我結束了重構那些線接口

Process start(String param) throws IOException; 

我現在把這個接口的實例到我想測試類(在其構造),通常使用原始行的默認實現。當我想測試時,我只需使用接口的模擬實現。像魅力一樣工作,雖然我不知道我是否過度接口在這裏...

回答

10

保護自己免受要嘲笑的課程。創建一個接口,用於完成您真正想要的任務(例如隱藏外部進程涉及的事實)或者僅用於Process和ProcessBuilder。

您不想測試,即ProcessBuilder和Process工作,只有您可以使用它們的輸出。當你創建一個接口時,一個簡單的實現(可以很容易地檢查)實現了ProcessBuilder和Process的委託,另一個實現模擬了這種行爲。稍後,您甚至可能會有另一個實現,在不啓動另一個進程的情況下執行您所需的操作

2

隨着更新版本的JMockit(0.98+),你應該能夠輕鬆地模擬JRE類,如Process和ProcessBuilder。所以,沒有必要創建只是用於測試接口...

完整的示例(使用JMockit 1.16):

public class MyProcessTest 
{ 
    public static class MyProcess { 
     public byte[] run() throws IOException, InterruptedException { 
      Process process = new ProcessBuilder("my.exe").start(); 
      process.waitFor(); 

      // Simplified example solution: 
      InputStream processOutput = process.getInputStream(); 
      byte[] output = new byte[8192]; 
      int bytesRead = processOutput.read(output); 

      return Arrays.copyOf(output, bytesRead); 
     } 
    } 

    @Test 
    public void runProcessReadingItsOutput(@Mocked final ProcessBuilder pb) 
     throws Exception 
    { 
     byte[] expectedOutput = "mocked output".getBytes(); 
     final InputStream output = new ByteArrayInputStream(expectedOutput); 
     new Expectations() {{ pb.start().getInputStream(); result = output; }}; 

     byte[] processOutput = new MyProcess().run(); 

     assertArrayEquals(expectedOutput, processOutput); 
    } 
} 
+0

如果你不想在所有執行my.exe? – 2015-05-28 20:07:38

相關問題