【问题标题】:Cannot powermock ProcessBuilder无法对 ProcessBuilder 进行 powermock
【发布时间】:2017-03-06 06:54:02
【问题描述】:

我在模拟 ProcessBuilder 的构造函数时遇到了问题。 ProcessBuilder 对象未被模拟,而是 new 返回 null。代码:

import java.util.concurrent.Executors;

public class Runner {
    private ProcessBuilder processBuilder;

    public ProcessBuilder getProcessBuilder() {
        return processBuilder;
    }

    public void run() {
        processBuilder = new ProcessBuilder("command", "parameter");
    }

    public void runInSubclass() {
        final SubRunner subRunner = new SubRunner();
        subRunner.run();
    }

    public void runInThread() {
        Executors.newSingleThreadExecutor().execute(new SubRunner());
    }

    private class SubRunner extends Thread {
        public void run() {
            processBuilder = new ProcessBuilder("command", "parameter");
        }
    }
}

测试(全部失败):

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.whenNew;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Runner.class)
public class RunnerTest {
    private Runner runner;

    @Before
    public void setUp() throws Exception {
        runner = new Runner();
        ProcessBuilder processBuilderMock = mock(ProcessBuilder.class);

        whenNew(ProcessBuilder.class).withAnyArguments().thenReturn(processBuilderMock);
    }

    @Test
    public void run() throws Exception {
        runner.run();
        assertThat(runner.getProcessBuilder(), is(not(nullValue())));
    }

    @Test
    public void runInSubclass() throws Exception {
        runner.runInSubclass();
        assertThat(runner.getProcessBuilder(), is(not(nullValue())));
    }

    @Test
    public void runInThread() throws Exception {
        runner.runInThread();
        Thread.sleep(100);
        assertThat(runner.getProcessBuilder(), is(not(nullValue())));
    }
}

我正在使用最新的 PowerMock (1.6.6)。

【问题讨论】:

  • I've got problems ... 请解释到底发生了什么以及为什么会出现问题
  • @defaultlocale,已更新。 new 返回 null 并且所有测试都失败。

标签: java testing junit powermock processbuilder


【解决方案1】:

你不需要 PowerMock 来解决这个问题。

您的问题是您在生产代码中到处都在调用 new。相反,您可以使用依赖注入,例如:

public class Runner {
...

  public Runner() {
    this ( new ProcessBuilder() );
  }

  Runner(ProcessBuilder builder) {...

突然之间,您有了一个“伸缩式”构造函数,允许您注入您的依赖项(一个 ProcessBuilder 对象)。突然之间,您使用 PowerMock 调用 new 的需求消失了。

关键是:PowerMock 是“昂贵的”;因为它有一些“坏”的副作用。只需避免使用它。

除此之外:PowerMock 应该可以很好地完成这项工作;只需根据他们的说明检查您的代码(可找到here);但如前所述:真正的答案是将 PowerMock 用于此类事情。相反:学习编写testable 代码。

【讨论】:

  • 完全同意:“干脆避免使用它。”和“学习编写可测试的代码。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 2023-03-03
  • 1970-01-01
  • 2018-03-25
  • 2018-11-03
  • 1970-01-01
  • 2012-09-04
相关资源
最近更新 更多