Reputation: 16972
Given this method in a Java class:
public void execute(String command) {
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
int exitValue = process.waitFor();
if (exitValue != 0) {
throw new RuntimeException("a message here...");
}
}
I'm trying to come up with a proper cross platform unit test for this method.
I'm looking for a common command across all operating systems (Win, Linux, Mac and ...) or a fake command that I can pass to this method in my unit tests.
Any suggestion ?
Upvotes: 5
Views: 3327
Reputation: 29530
This method can't be tested via a unit test but only via an integration test. To make a unit test you could do a small refactor. Introduce a new interface ProcessBuilderFactory
(and a default implementation) and inject it on your class.
public interface ProcessBuilderFactory {
ProcessBuilder createProcessBuilder(String command);
}
public class DefaultProcessBuilderFactory implements ProcessBuilderFactory {
public ProcessBuilder createProcessBuilder(String command) {
return new ProcessBuilder(command);
}
}
public class ProcessExecutor {
private ProcessBuilderFactory processBuilderFactory;
private ProcessExecutor(ProcessBuilderFactory processBuilderFactory) {
this.processBuilderFactory = processBuilderFactory;
}
public void execute(String command) {
ProcessBuilder processBuilder = processBuilderFactory.createProcessBuilder(command);
Process process = processBuilder.start();
int exitValue = process.waitFor();
if (exitValue != 0) {
throw new RuntimeException("a message here...");
}
}
}
and then you could make a unit test by injecting a mock ProcessBuilderFactory
.
You start writing the test, you create a mock ProcessBuilderFactory
, returning a mock ProcessBuilder
... damned, ProcessBuilder
is final
too :(
A strong reminder : write the test first !
So we have two options :
ProcessBuilder
with a default implementation... in the same way we create the ProcessBuilderFactory
Upvotes: 8
Reputation: 18458
Since this is java unit test you could use java.exe as standard exe. Say java.exe -version
. It will always be there :). Use current jdk from java.home and then use that to refer java.exe
Looking at specific requirement could you use any mocking framework? (jmockit for example)
Upvotes: 2