当我尝试对ProcessBuilder
构造函数进行powermock时,如果参数是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)
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);
Powermock正在拦截对ProcessBuilder varargs构造函数的调用,因为PowerMockito.whenNew(ProcessBuilder.class).withParameterTypes(String[].class)
与varargs构造器匹配。但是,由于withArguments(isA(String[].class))
不匹配,thenReturn被忽略,Powermock只返回null而不是pb mock。
另请参阅如何在Mockito 中正确匹配varargs