如何在使用 (Power)Mockito 初始化 class 时模拟私有静态方法的静态调用?

How to mock static call of a private static method in initialization of the class with (Power)Mockito?

我有一个奇怪的情况,这是由于一些糟糕的设计造成的,但这是我需要接受的事实。问题是它让我在模拟时遇到问题,因为有问题的方法在尝试查找构建机器上不存在的某些本地文件时会产生副作用。

是这样的:

class BadDesignedClass {
    public static final Properies = loadProperties();
    private static Properties loadProperties() {
        // ... loads non-existent property file and crashes...
    }
}

我无法对此进行模拟,因为目前我在测试 class 中提到了 class 它调用了真正的 loadProperties() ,这是在 Mockito 或 PowerMockito 进行任何模拟之前,这会导致抛出错误。

加载 class 而不初始化它(详细信息可以在 this answer 中找到)。那么 loadProperties 将不会被调用。这可以通过以下方式实现。

Class<?> clazz = Thread.currentThread().getContextClassLoader()
    .loadClass("org.example.BadDesignedClass");

然后你可以将 clazz 传递给 PowerMockito。

为了获得完整的解决方案,我将在此处展示我的具体做法,灵感来自 SpaceTrucker 的建议:

首先:加载class没有初始化:

Class<?> clazz = Thread.currentThread().getContextClassLoader()
        .loadClass("org.example.BadDesignedClass");

其次:抑制所有问题的静态方法。

PowerMockito.suppress(PowerMockito.method(clazz , "loadProperties"));

第三:继续像往常一样模拟class,因为loadProperties()现在被抑制了。

PowerMockito.mockStatic(BadDesignedClass.class);
PowerMockito.when(BadDesignedClass.someMethod()).thenReturn("something");