2008-10-16 49 views
7

Tôi có một phương thức Java khởi động một Process với ProcessBuilder, và đưa đầu ra của nó vào một mảng byte, và sau đó trả về mảng byte của nó khi quá trình kết thúc.Làm cách nào để đơn vị thử nghiệm một phương thức Java sử dụng ProcessBuilder và Process?

Pseudo-code:

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

Điều gì sẽ là cách tốt nhất để đi về đơn vị thử nghiệm phương pháp này? Tôi đã không tìm thấy một cách để thử ProcessBuilder (nó chính thức), ngay cả với những vô cùng tuyệt vời JMockit, nó mang lại cho tôi một 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) 

Bất kỳ suy nghĩ?


trả lời - Như Olaf đề nghị, tôi đã kết thúc refactoring những dòng để một giao diện

Process start(String param) throws IOException; 

bây giờ tôi vượt qua một thể hiện của giao diện này vào lớp tôi muốn thử nghiệm (trong constructor của nó), thường sử dụng triển khai mặc định với các dòng gốc. Khi tôi muốn thử nghiệm, tôi chỉ đơn giản là sử dụng thực hiện mô hình của giao diện. Hoạt động như một sự quyến rũ, mặc dù tôi tự hỏi liệu tôi có đang giao tiếp quá mức ở đây không ...

Trả lời

10

Tự bảo vệ mình khỏi các lớp học được chế nhạo. Tạo giao diện để thực hiện những gì bạn thực sự muốn (ví dụ: ẩn thực tế là các quy trình bên ngoài có liên quan) hoặc chỉ dành cho Process và ProcessBuilder.

Bạn không muốn kiểm tra, ProcessBuilder và quy trình làm việc đó, chỉ bạn mới có thể làm việc với đầu ra của chúng. Khi bạn tạo một giao diện một triển khai tầm thường (có thể được kiểm tra một cách dễ dàng) các đại biểu đến ProcessBuilder và Process, một thực thi khác sẽ mô phỏng hành vi này. Sau đó, bạn thậm chí có thể có một triển khai khác thực hiện những gì bạn cần mà không cần bắt đầu quá trình khác.

2

Với các phiên bản mới hơn của JMockit (0.98+), bạn sẽ có thể dễ dàng giả lập các lớp JRE như Process và ProcessBuilder. Vì vậy, không cần phải tạo ra các giao diện chỉ để thử nghiệm ...

Full dụ (sử dụng 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

gì nếu bạn không muốn thực hiện my.exe ở tất cả? –

+0

@DavidI. Các thử nghiệm được hiển thị ở trên không có nghĩa là, nó không thực hiện "my.exe". –

+0

Cảm ơn, tôi là một người mới chơi JMockit, vì vậy lúc đầu tôi không hiểu. (nhưng tôi là một fan hâm mộ lớn!) –

Các vấn đề liên quan