java - Powermockito - 无法模拟/监视系统类

标签 java unit-testing mockito powermock powermockito

我正在尝试模拟 java.nio.file.Files 类中的静态方法,如下所示:

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

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Files.class})
public class MockStaticTest {

    @Test
    public void test() throws IOException {
        Path absolutePath = Paths.get("AB", "CD", "EF");
        mockStatic(Files.class);
        when(Files.createDirectories(absolutePath)).thenReturn(null);
    }
}

当我执行测试类时,出现此异常:

org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class java.nio.file.Files
Mockito cannot mock/spy because :
 - final class

    at MockStaticTest.test(MockStaticTest.java:22)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


Process finished with exit code -1

但是,如果我尝试模拟任何其他最终类,它可以正常工作,没有任何问题,例如:

import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest({Files.class, NettyChannelBuilder.class})
public class MockStaticTest {

    @Test
    public void test() throws IOException {
        Path absolutePath = Paths.get("AB", "CD", "EF");
//        mockStatic(Files.class);
        mockStatic(NettyChannelBuilder.class);
//        when(Files.createDirectories(absolutePath)).thenReturn(null);
        when(NettyChannelBuilder.forAddress("", 0)).thenReturn(null);
    }
}

有人可以帮我解决这个问题吗?为什么 Files 类抛出模拟异常?

Maven 依赖项:

         <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>2.0.2</version>
            <scope>test</scope>
          </dependency>

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>2.28.2</version>
      <scope>test</scope>
    </dependency>

最佳答案

Mockito 和 PowerMock 版本之间不匹配。检查Powermock documentation用于版本对齐。

这是我用来重现问题的 Maven 设置(文件制动,与 NettyChannelBuilder 配合良好):

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>3.0.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-core</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>2.0.0</version>
        <scope>test</scope>
    </dependency>

如果我切换到 Mockito 2.10.0,这两个类都可以工作:

   <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.10.0</version>
        <scope>test</scope>
    </dependency>

关于java - Powermockito - 无法模拟/监视系统类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57873469/

相关文章:

c# - 是否有必要模拟单元测试中的所有依赖项?

unit-testing - 如何在 Dart 中测试 Web 组件?

android - Mockito 无法模拟/监视,因为 : - final class

java - JUnit 示例程序编译但给出运行时错误

java - 为什么 Servlet.service() 方法返回 void 而不是 ServletResponse 的实例?

java - 我应该将不被视为资源的配置文件放在 maven 项目的路径中的哪个位置

Android Studio 简单单元测试不起作用

java - 如何模拟当前日期?

java - 当方法位于基类内部并且测试方法类扩展它时,如何在 JUnit 中模拟方法调用?

java - 并行化 REST 调用的最佳方式是什么?