防止特殊 class 来自静态模拟

Prevent special class from static mocking

我有一个名为 SpecialClass 的 class。这个class里面有方法doSomething。这个 class 以这种特殊的方式很特别,我根本不想通过 MockedStatic 来嘲笑这个 class。我很容易记住我不想模拟这个 class,但是在同一个项目中还有其他人在编程,他们应该知道不要模拟这个 class 但我不能与之相关。

鉴于此特殊测试:

@Test
void testSomething(){
    try(MockedStatic<SpecialClass> mock = Mockito.mockStatic(SpecialClass.class)){

        mock.when(SpecialClass::doSomething).thenReturn(0);

         System.out.println(SpecialClass.doSomething());
    }
}

我根本不想让这个测试执行。但它会执行,因为 Mockito 不知道我的 SpecialClass 也不会模拟它。还可以在其他各种位置模拟 SpecialClass。

一些 classes 不能被模拟,因为 Mockito 决定这样做。鉴于 java.lang.System 的这个模拟:

@Test
void testFail(){
    try(MockedStatic<System> sys = Mockito.mockStatic(System.class)){
        // some code
    }
}

我得到异常 org.mockito.exceptions.base.MockitoException: It is not possible to mock static methods of java.lang.System to avoid interfering with class loading what leads to infinite loops,没关系。

我的问题是:我能否以某种方式设置一些全局项目设置(或一些注释)来标记我的 class SpecialClass 不在 Mockitos MockedStatic 中使用?如果我也不能以正常方式嘲笑这个 class 我也可以。

我试图找到一些关于限制模拟的信息,但找不到。

我的 mockito-core 和 mockito-inline 的 mockito 版本是 4.3.1

我使用了 junit 测试来读取我的所有文件并尝试检测所有模拟。 请注意,我的测试是在一个非常特殊的假设下进行的,即我的所有测试 类 都在同一个目录中。这不会在每个项目中都给出。在这种情况下,您需要找到 the files recursivly.

class NoStaticMockTest {

    @Test
    void testNoMocks() throws IOException {
        // Base dir of my tests
        File testDir = new File("src/test/java");
        // reading all Files in the test directory excluding this file
        for (File file : testDir.listFiles(pathname -> !pathname.getAbsolutePath().endsWith("NoStaticMockTest.java") && pathname.isFile())) {
            try (FileInputStream fis = new FileInputStream(file)) {
                // Reading the contennt and trying to find MockedStatic<SpecialClass>
                String content = IOUtils.toString(fis);
                if (content.contains("MockedStatic<SpecialClass>")) {
                    Assertions.fail(file.getAbsolutePath() + " used MockedStatic<SpecialClass> which is not allowed");
                }
            }
        }
    }

}