2008-10-16 16 views
7

ProcessBuilder ile bir İşlemi başlatan ve çıktısını bir bayt dizisine bağlayan ve sonra işlem bittiğinde bayt dizisini döndüren bir Java yöntemim var.Ünite, ProcessBuilder ve Process kullanan bir Java yöntemini nasıl test edebilirim?

Sözde kod:

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

Ne bu yöntemi test birim hakkında gitmek için en iyi yolu olurdu?

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) 

Herhangi düşünceler: Bunun beni NoClassDefFoundError verir hatta inanılmaz müthiş JMockit ile, (o nihai) ProcessBuilder alay için bir yol bulmuş değil mi?


Cevap - Olaf tavsiye, ben onun kurucu (şimdi ben test etmek istedim sınıfa Bu arayüz bir örneğini geçmesi bir arayüz

Process start(String param) throws IOException; 

için bu satırları üstlenmeden sona erdi), normalde orijinal satırlarla varsayılan bir uygulama kullanarak. Test etmek istediğimde, sadece arayüzün sahte bir uygulamasını kullanıyorum. Bir çekicilik gibi çalışır, yine de burada fazla bir arayüz olup olmadığımı merak ediyorum ...

cevap

10

Kendinizi alay edilecek sınıflardan koruyun. Gerçekten istediğiniz şeyi yapmak için bir arabirim oluşturun (örneğin, dış işlemlerin dahil olduğu gerçeğini gizlemek gibi) veya yalnızca İşlem ve İşlem Yapıcı için.

Bunu yapmak istemiyorsanız, ProcessBuilder ve Process işlerini, yalnızca çıktılarıyla çalışabileceğinizi test etmek istemezsiniz. Bir arabirim oluşturduğunuzda, bir önemsiz uygulama (kolayca denetlenebilir) ProcessBuilder ve Process'e delege verir, başka bir uygulama bu davranışı alay eder. Daha sonra başka bir işleme başlamadan ihtiyacınız olanı yapan başka bir uygulama bile olabilir.

2

Daha yeni JMockit sürümleri (0.98+) ile, Proses ve ProcessBuilder gibi JRE sınıflarını kolayca kullanabilmeniz gerekir. Yani, gerek yok ... (JMockit 1.16 kullanarak)

Tam örnek sadece test için arayüzleri oluşturmak için:

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

Ne sen hiç my.exe yürütmek istemediğini olur? –

+0

@DavidI. Yukarıda gösterilen test, yani "my.exe" yi çalıştırmaz. –

+0

Teşekkürler, ben bir JMockit acemi, bu yüzden ilk başta anlamadım. (ama ben büyük bir hayranıyım!) –

İlgili konular