1

我正在使用 powermock 使用进程构建器来模拟一些本机命令调用。奇怪的是这些测试有时会通过,有时会失败,给出 NPE。这是一个powermock问题还是程序中的一些问题。

这是我正在测试的课程的片段:

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);
  }
}

单元测试用例是:

@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);
  }
}

我在执行时遇到错误,并且测试用例失败..

Caused by: java.lang.NullPointerException
at java.lang.ProcessBuilder.start(ProcessBuilder.java:438)

注意:我在所有执行中都没有收到此错误。有时它通过,有时它失败。我无法理解这种行为。另外,由于版权问题,我伪装了一些变量名。

4

1 回答 1

0

由于您正在模拟构造函数调用,因此您必须将代码准备为墙。这是因为构造函数调用是代码的一部分。在 PowerMock 文档中阅读更多信息: http ://code.google.com/p/powermock/wiki/MockConstructor

于 2010-08-27T08:04:18.793 回答