Powermock: ProcessBuilder redirectErrorStream дает исключение nullPointerException - PullRequest
1 голос
/ 10 мая 2010

Я использую 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)

Примечание: я не получаю эту ошибку при всех выполнениях. Иногда это проходит, а иногда это не удается. Я не могу понять это поведение. Кроме того, я замаскировал некоторые имена переменных из-за проблем с авторским правом.

1 Ответ

0 голосов
/ 27 августа 2010

Поскольку вы издеваетесь над вызовом конструктора, вы должны подготовить свой код как стену. Это потому, что вызов конструктора является частью вашего кода. Узнайте больше в документации PowerMock: http://code.google.com/p/powermock/wiki/MockConstructor

...