2008-10-16 2 views
7

ProcessBuilder를 사용하여 Process를 시작하고 출력을 바이트 배열로 파이프 한 다음 프로세스가 완료되면 바이트 배열을 반환하는 Java 메서드가 있습니다.ProcessBuilder 및 프로세스를 사용하는 Java 메소드를 어떻게 테스트합니까?

의사 코드 :

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

은 무엇이 방법을 테스트 장치에 대해 이동하는 가장 좋은 방법이 있을까요?

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) 

어떤 생각 : 나는 그것이 나에게 NoClassDefFoundError를 제공, 심지어는 믿을 수 없을만큼 멋진 JMockit으로, (그것의 최종) ProcessBuilder를 조롱하는 방법을 발견하지?


대답은 - 올라프가 권장하는대로, 나는 그것의 생성자에서 (나는 지금 테스트하고 싶은 클래스로이 인터페이스의 인스턴스를 전달하는 인터페이스

Process start(String param) throws IOException; 

에 그 라인을 리팩토링 결국), 일반적으로 원래의 행을 사용하여 기본 구현을 사용합니다. 테스트하고 싶을 때 인터페이스의 모의 구현을 사용하기 만하면됩니다. 매력처럼 작동합니다. 비록 제가 여기에 넘치는 인터페이스가 있는지 궁금합니다.

답변

10

조롱받을 수업에서 자신을 보호하십시오. 정말로 원하는 것 (예 : 외부 프로세스가 전혀 포함되지 않는다는 사실을 숨기는 것) 또는 Process 및 ProcessBuilder에 대해서만 인터페이스를 만들 수 있습니다.

해당 ProcessBuilder 및 프로세스 작업을 테스트하고 싶지는 않으며 출력 결과로만 작업 할 수 있습니다. 인터페이스를 만들면 쉽게 검사 할 수있는 간단한 구현이 ProcessBuilder 및 Process에 위임되며 다른 구현은이 동작을 모의합니다. 나중에 다른 프로세스를 시작하지 않고도 필요한 것을 구현하는 또 다른 구현을 할 수도 있습니다.

2

JMockit (0.98 이상)의 최신 릴리스에서는 Process 및 ProcessBuilder와 같은 JRE 클래스를 쉽게 조롱 할 수 있어야합니다. 그래서, 필요 (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을 실행하지 않은 경우? –

+0

@DavidI. 위에 표시된 테스트는 즉, "my.exe"를 실행하지 않습니다. –

+0

고마워, 나는 JMockit 초보자이다. 그래서 나는 처음에 이해하지 못했다. (하지만 난 큰 팬이야!) –

관련 문제