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

时间:2019-09-10 14:57:34

标签: 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>

1 个答案:

答案 0 :(得分:1)

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>