Powermock ProcessBuilder构造函数,带有String [] .class参数

时间:2013-08-06 21:17:36

标签: junit constructor mockito powermock

当我尝试使用ProcessBuilder构造函数时,如果参数是一个ArrayList,它会成功,但是当参数是一个String数组时它会失败。

要测试的课程是:

package test;

import java.util.ArrayList;


public class MockProcessBuilder {

public void instance1() throws Exception {

    String chmodCmd[] = { "/bin/chmod", "755", "/path/to/dest" + "/" + "file.txt" };

    // constructor with String[].class
    ProcessBuilder pb = new ProcessBuilder(chmodCmd);

    pb.redirectErrorStream(true);

    Process proc = pb.start();

    proc.waitFor();
}

public void instance2() throws Exception {

    ArrayList<String> cmdArrayList = new ArrayList<String>();
    cmdArrayList.add("/bin/execScript");
    cmdArrayList.add("exec");
    cmdArrayList.add("ls -altr");

    // constructor with ArrayList.class             
    ProcessBuilder pb = new ProcessBuilder(cmdArrayList);

    pb.redirectErrorStream(true);

    Process proc = pb.start();

    proc.waitFor();
}
}

测试类是:

package test;

import static org.mockito.Matchers.isA;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.ArrayList;
import java.util.List;

@RunWith(PowerMockRunner.class)
@PrepareForTest({MockProcessBuilder.class, ProcessBuilder.class})
public class MockProcessBuilderTest {

@Mock ProcessBuilder pb;
@Mock Process proc;

    // fail. NullPointerException
@Test
public void testInstance1() throws Exception {

    PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(String[].class).withArguments(isA(String[].class)).thenReturn(pb);
    Mockito.when(pb.start()).thenReturn(proc);

    MockProcessBuilder mpb = new MockProcessBuilder();

    mpb.instance1();
}


    // success
@Test
public void testInstance2() throws Exception {

    PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(List.class).withArguments(isA(ArrayList.class)).thenReturn(pb);
    Mockito.when(pb.start()).thenReturn(proc);

    MockProcessBuilder mpb = new MockProcessBuilder();

    mpb.instance2();
}

 }

第一个测试用例失败并出现错误:

java.lang.NullPointerException

有谁知道如何模拟第一个构造函数?

由于

修改 的 完整的痕迹:

java.lang.NullPointerException
at test.MockProcessBuilder.instance1(MockProcessBuilder.java:14)
at test.MockProcessBuilderTest.testInstance1(MockProcessBuilderTest.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

1 个答案:

答案 0 :(得分:1)

testInstance1()测试失败,因为参数匹配器isA(String[].class)与您给出的String varargs参数不匹配。要使测试通过,请替换testInstance1()行

PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(String[].class).
             withArguments(isA(String[].class)).thenReturn(pb);

PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(String[].class).
             withArguments(anyVararg()).thenReturn(pb);

由于PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(String[].class)匹配varargs构造函数,Powermock正在拦截对ProcessBuilder varargs构造函数的调用。但是,由于withArguments(isA(String[].class))不匹配,thenReturn会被忽略,而Powermock只返回null而不是pb mock。

另见How to properly match varargs in Mockito