2

当我尝试对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)
4

1 回答 1

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)匹配可变参数构造函数,Powermock 正在拦截对 ProcessBuilder 可变参数构造函数的调用。但是,因为withArguments(isA(String[].class))不匹配,thenReturn 被忽略,Powermock 只返回 null 而不是 pb 模拟。

另请参阅如何正确匹配 Mockito 中的可变参数

于 2013-11-15T21:00:03.267 回答