如何使用由静态初始化程序调用的 PowerMockito 模拟 java 中的私有静态方法?

how to mock private static method in java with PowerMockito which invoked by static Initializer?

我正在尝试模拟如下所示的静态方法,但我被静态初始化程序阻止了。请参阅下面的代码:

public class StaticInitializerService {

static{
    init();
}

private static void init(){
    throw new UnsupportedOperationException();
}

private static String getString(){
    throw new UnsupportedOperationException();
}

public static String method(){
    return getString();
}
}

这是我的测试用例:

@PrepareForTest(StaticInitializerService.class)
public class StaticInitializerServiceTest   extends PowerMockTestCase{
@ObjectFactory
public ITestObjectFactory getObjectFactory() {
    return new PowerMockObjectFactory();
}

@Test
public void method() {
  PowerMockito.mockStatic(StaticInitializerService.class);
}
}

我正在尝试使用 mockstatic 和 spy,它们都会引发以下异常:

java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor4.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:14)
at org.powermock.api.mockito.repackaged.ClassImposterizer.createProxy(ClassImposterizer.java:143)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:58)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:111)
at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:59)
at org.powermock.api.mockito.PowerMockito.spy(PowerMockito.java:234)
at com.zghome.mvndemo.TestNGDemo.powermock.service.testng.StaticInitializerServiceTest.method(StaticInitializerServiceTest.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
at org.testng.TestRunner.privateRun(TestRunner.java:774)
at org.testng.TestRunner.run(TestRunner.java:624)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
at org.testng.SuiteRunner.run(SuiteRunner.java:261)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1215)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.run(TestNG.java:1048)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:126)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:152)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:57)
Caused by: java.lang.UnsupportedOperationException
at     com.zghome.mvndemo.TestNGDemo.powermock.service.StaticInitializerService.init(St aticInitializerService.java:10)
at com.zghome.mvndemo.TestNGDemo.powermock.service.StaticInitializerService.  <clinit>(StaticInitializerService.java:6)
... 35 more

我想我不能像这样嘲笑这个 class,但我不知道如何嘲笑这个。有什么办法可以解决吗?

请添加以下行以避免上述异常

@SuppressStaticInitializationFor("packageName.StaticInitializerService")

然后模拟的其余部分将类似于静态无效方法模拟和 PowerMockito.doThrow() 方法来表明 exception.here 是示例代码,它不会为您的 [=18 抛出任何异常=]

    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
    import org.powermock.modules.junit4.PowerMockRunner;
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(StaticInitializerService.class)
    @SuppressStaticInitializationFor("PackageName.StaticInitializerService")
    public class StaticInitializerServiceTest {
    @Test 
    public void method() {
    PowerMockito.mockStatic(StaticInitializerService.class);
    }   
  }