java - 使用 powerMockito 在 Runnable 中模拟 new()

标签 java unit-testing mockito inner-classes powermockito

我有这个类,我试图在其中模拟 UrlWrapper.class 的对象创建

public class WorkerClass {
  private final String url;

  public WorkerClass(String url) {
    this.url = url;
  }

  void performOperation(Executor executor) throws IOException {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            UrlWrapper urlWrapper = null;
            try {
                urlWrapper = new UrlWrapper(url);
                HttpURLConnection connection = (HttpURLConnection) urlWrapper.openConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    };
    executor.execute(runnable);
  }
}

这是我尝试过的测试代码

@RunWith(PowerMockRunner.class)
@PrepareForTest({UrlWrapper.class, WorkerClass.class})
public class TestClass {
  @Before
  public void init() throws Exception {
    UrlWrapper urlWrapper = Mockito.mock(UrlWrapper.class);
    PowerMockito.whenNew(UrlWrapper.class)
                .withArguments(Mockito.anyString())
                .thenReturn(urlWrapper);
  }

  @Test
  public void test() throws IOException {
    Executor executor = new Executor() {
        @Override
        public void execute(Runnable command) {
            command.run();
        }
    };

    WorkerClass workerClass = new WorkerClass("");
    workerClass.performOperation(executor);
  }
}

但它并没有被 mock 。模拟在没有 Runnable 的情况下也能正常工作。

我在这里缺少什么?

最佳答案

您的问题在这里:

@PrepareForTest({UrlWrapper.class, WorkerClass.class

还有:

Runnable runnable = new Runnable() {

事情是:您没有Worker类中调用new。您正在创建一个 Worker 的匿名内部类(即 Runnable 实例化) - 并且您正在执行 new 调用。

我看到两个选项:

  • 当然,那个匿名内部类......实际上有一个类名。因此,也许您可以使用“损坏的”类名,并将其传递给@PrepareForTest
  • 避免以这种方式调用new

我相当怀疑你是否选择了第一个工作选项。即使这有效,也可能是一些非常肮脏的解决方法。

真正的答案是:学习如何编写可测试代码,例如通过观看这些 videos 。您的真正问题是对new的调用。一种解决方案:创建一个为您提供 URL 对象的工厂;然后使用依赖注入(inject)来获取可运行对象中的工厂。

无需 PowerMock(ito) 即可模拟该工厂...突然间,您的整个设计得到了改进;同时它变得更容易测试。

关于java - 使用 powerMockito 在 Runnable 中模拟 new(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44669211/

相关文章:

java - 无法将 war 复制到 Google 存储桶

java.lang.RuntimeException : Unable to instantiate application com. chiaramail.chiaramailforandroid.K9

java - 在 Mockito 中使用泛型处理匿名类

java - Spring Mockito TestNG - 模拟在测试中持续存在

java - 无法导入 springframework.security.extensions 并找到 saml() 方法

java - WAS 服务器中的 org/codehaus/jackson/map/ObjectMapper.setSerializationInclusion 异常

安卓, Gradle 。如何构建应用程序并从测试应用程序运行测试

c# - Arg<object>.Is.Equal 与匿名对象

java - Mockito 异常 : Missing method invocation while trying to test an if conditon

java - 模拟一个具体的类——它总是空的