2008-10-16 76 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

相关问题