Powermock: ProcessBuilder redirectErrorStream giving nullPointerException
I am using powermock to mock some native command invocation using process builder. the strange thing is these test pass sometimes and fail sometimes giving a NPE. Is this a powermock issue or some gotcha in the program.
Here is a 开发者_如何学Gosnippet of the class I am testing:
public void method1(String jsonString, String filename) {
try {
JSONObject jObj = new JSONObject(jsonString);
JSONArray jArr = jObj.getJSONArray("something");
String cmd = "/home/y/bin/perl <perlscript>.pl<someConstant>" + " -k " + <someConstant> + " -t " + <someConstant>;
cmd += vmArr.getJSONObject(i).getString("jsonKey");
ProcessBuilder pb = new ProcessBuilder("bash", "-c", cmd);
pb.redirectErrorStream(false);
Process shell = pb.start();
shell.waitFor();
if (shell.exitValue() != 0) {
throw new RuntimeException("Error in Collecting the logs. cmd="+cmd);
}
StringBuilder error = new StringBuilder();
InputStream iError = shell.getErrorStream();
BufferedReader bfr =
new BufferedReader(
new InputStreamReader(iError));
String line = null;
while ((line = bfr.readLine()) != null) {
error.append(line + "\n");
}
if (!error.toString().isEmpty()) {
LOGGER.error(error`enter code here`);
}
iError.close();
bfr.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
and the unit test case is:
@PrepareForTest( {<Classtobetested>.class, ProcessBuilder.class,Process.class, InputStream.class,InputStreamReader.class, BufferedReader.class} )
@Test(sequential=true)
public class TestClass {
@Test(groups = {"unit"})
public void testMethod() {
try {
ProcessBuilder prBuilderMock = createMock(ProcessBuilder.class);
Process processMock = createMock(Process.class);
InputStream iStreamMock = createMock(InputStream.class);
InputStreamReader iStrRdrMock = createMock(InputStreamReader.class);
BufferedReader bRdrMock = createMock(BufferedReader.class);
String errorStr =" Error occured";
String json = <jsonStringInput>;
String cmd = "/home/y/bin/perl <perlscript>.pl -k "+<someConstant>+" -t "+<someConstant>+" "+<jsonValue>;
expectNew(ProcessBuilder.class, "bash", "-c", cmd).andReturn(prBuilderMock);
expect(prBuilderMock.redirectErrorStream(false)).andReturn(prBuilderMock);
expect(prBuilderMock.start()).andReturn(processMock);
expect(processMock.waitFor()).andReturn(0);
expect(processMock.exitValue()).andReturn(0);
expect(processMock.getErrorStream()).andReturn(iStreamMock);
expectNew(InputStreamReader.class, iStreamMock)
.andReturn(iStrRdrMock);
expectNew(BufferedReader.class, iStrRdrMock)
.andReturn(bRdrMock);
expect(bRdrMock.readLine()).andReturn(errorStr);
expect(bRdrMock.readLine()).andReturn(null);
iStreamMock.close();
bRdrMock.close();
expectLastCall().once();
replayAll();
<ClassToBeTested> instance = new <ClassToBeTested>();
instance.method1(json, fileName);
verifyAll();
} catch (Exception e) {
Assert.fail("failed while collecting log.", e);
}
}
I get an error on execution and the test case fails..
Caused by: java.lang.NullPointerException
at java.lang.ProcessBuilder.start(ProcessBuilder.java:438)
Note: I do not get this error on all executions. Sometimes it passes and sometimes it fails. I am not able to understand this behavior. Also, I have camouflaged some variable names because of the copyright issues.
Since your are mocking the constructor call you have to prepare your code as wall. This is because the constructor invocation is part of your code. Read more in the PowerMock documentation: http://code.google.com/p/powermock/wiki/MockConstructor
精彩评论