Frage

Ich habe ein Java-Verfahren, das einen Prozess mit Process startet, und Rohre seinem Ausgang in ein Byte-Array, und kehrt dann seine Byte-Array, wenn der Prozess beendet ist.

Pseudo-Code:

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

Was wäre der beste Weg, Einheit zu gehen, um diese Methode zu testen? Ich habe nicht einen Weg zu verspotten Process (es ist endgültig), auch mit dem unglaublich genial JMockit , es gibt mir ein NoClassDefFoundError gefunden :

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)

Alle Gedanken?


Antwort - Als Olaf empfohlen, landete ich diese Zeilen an eine Schnittstelle Refactoring bis

Process start(String param) throws IOException;

ich jetzt eine Instanz dieser Schnittstelle in die Klasse übergeben I (in seinem Konstruktor), in der Regel mit einer Standardimplementierung mit den ursprünglichen Linien testen wollte. Wenn ich testen möchte verwende ich einfach ein Mock-Implementierung der Schnittstelle. Funktioniert wie ein Zauber, obwohl ich frage mich, ob ich über Schnittstelle hier ...

War es hilfreich?

Lösung

Schild selbst aus den Klassen verspottet werden. Erstellen Sie eine Schnittstelle entweder für das, was Sie wirklich wollen (zum Beispiel die Tatsache versteckt, dass externe Prozesse überhaupt beteiligt sind) oder nur für Prozess- und Process.

Sie mögen, dass Process und Prozess nicht testen, Arbeit, nur, dass Sie mit ihrem Ausgang arbeiten können. Wenn Sie eine Schnittstelle eine triviale Implementierung schaffen (das leicht eingesehen werden kann) Delegierten Process und Verfahren, spottet eine andere Implementierung dieses Verhalten. Später könnten Sie sogar eine weitere Implementierung haben das tut, was Sie brauchen, ohne einen anderen Prozess zu starten.

Andere Tipps

Bei neueren Versionen von JMockit (0.98+) sollten Sie in der Lage sein, Klassen leicht Mock JRE wie Prozess- und Process. Also, keine Notwendigkeit, Schnittstellen schafft nur zum Testen ...

Voll Beispiel (unter Verwendung von 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);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top