java - Powermock ExceptionInInitializerError 与 Junit

标签 java spring junit powermock powermockito

单元测试设置

@RunWith(PowerMockRunner.class)
@PrepareForTest(PGWService.class)
public class PGWServiceTest {
public static final String TEST_CLIENTTRX_ID = "12345";
public static final int TEST_SITE_ID = 0;
public static final long TEST_USER_ID = 12345L;
public static final int TEST_CURRENCY_ID = 1;
public static final String TEST_ACCOUNT_TYPE = "Test account type";
public static final boolean TEST_IS_DEDUPING = false;
public static final byte[] TEST_SSN_CRYPT = new byte[] { 1, 2, 3 };
public static final byte[] TEST_TAX_ID_CRYPT = new byte[] { 1, 2, 3 };
public static final String TEST_SSN_LAST_FOUR = "1234";
public static final String TEST_TAX_ID_LAST_FOUR = "1234";

@Mock
PGWBaseRequest request;

@Mock
PGWClient client;

PGWService pGWService = new PGWService();

PGWGetAccountTaxIDResponse expectedResponse = this
        .buildGPWGetAccountIdResponse(TEST_SSN_CRYPT, TEST_TAX_ID_CRYPT,
                TEST_SSN_LAST_FOUR, TEST_TAX_ID_LAST_FOUR);

@Before
public void setUp() throws Exception {
    PowerMockito.mockStatic(PGWClient.class);
    PowerMockito.mockStatic(PGWBaseRequest.class);
    PowerMockito.when(PGWClient.getInstance()).thenReturn(client);
    PowerMockito
            .whenNew(PGWBaseRequest.class)
            .withArguments(TEST_CLIENTTRX_ID, TEST_SITE_ID, TEST_USER_ID,
                    TEST_CURRENCY_ID, TEST_ACCOUNT_TYPE, TEST_IS_DEDUPING)
            .thenReturn(request);
    PowerMockito.when(client.getTaxIdInformation(request)).thenReturn(
            expectedResponse);
}

@Test
public void testGetTaxIdInformationHappyPath() throws PGWException {

    PGWGetAccountTaxIDResponse actualResponse = pGWService
            .getTaxIdInformation(TEST_CLIENTTRX_ID, TEST_SITE_ID,
                    TEST_USER_ID, TEST_CURRENCY_ID, TEST_ACCOUNT_TYPE,
                    TEST_IS_DEDUPING);
    Assert.assertEquals(expectedResponse.getSSNLastFour(),
            actualResponse.getSSNLastFour());
}

private PGWGetAccountTaxIDResponse buildGPWGetAccountIdResponse(
        byte[] ssnCrypt, byte[] taxIdCrypt, String ssnLastFour,
        String taxIdLastFour) {
    PGWGetAccountTaxIDResponse response = new PGWGetAccountTaxIDResponse();
    response.setSSNCrypt(ssnCrypt);
    response.setSSNLastFour(ssnLastFour);
    response.setTaxIDCrypt(taxIdCrypt);
    response.setTaxIDLastFour(taxIdLastFour);
    return response;

}

}

我尝试运行单元测试,但测试实例失败,并出现以下错误

java.lang.ExceptionInInitializerError at sun.reflect.GeneratedSerializationConstructorAccessor7.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Constructor.java:526) at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:40) at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:59) at org.mockito.internal.creation.jmock.ClassImposterizer.createProxy(ClassImposterizer.java:128) at org.mockito.internal.creation.jmock.ClassImposterizer.imposterise(ClassImposterizer.java:63) at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMethodInvocationControl(MockCreator.java:111) at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:60) at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:143) at org.powermock.api.extension.listener.AnnotationEnabler.standardInject(AnnotationEnabler.java:84) at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:51) at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:90) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:292) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84) at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118) at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104) at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.NullPointerException at at com.bdd.domain.biz.pgwclient.DynamicConfigListener.getAttributeValue(DynamicConfigListener.java:132) at com.bdd.domain.biz.pgwclient.PGWCommunicator.init(PGWCommunicator.java:95) at com.ebay.domain.biz.pgwclient.PGWCommunicator.(PGWCommunicator.java:83) at com.bdd.domain.biz.pgwclient.PGWCommunicator.getInstance(PGWCommunicator.java:62) at com.bdd.domain.biz.pgwclient.PGWClient.(PGWClient.java:117)

最佳答案

当您尝试使用 PowerMock 模拟静态方法时,它会在内部创建该类的实例。所以当你

PowerMockito.mockStatic(PGWClient.class);

该类的新实例是在 PowerMock 内部创建的。您的 PGWClient 类默认构造函数此时会调用静态方法进行一些初始化。这会导致静态模拟失败。

您应该检查 Power Mock Suppressing Unwanted Behavior

<小时/>

编辑

从堆栈跟踪中可以看出 PGWClient 正在访问 PGWCommunicator 通过 getInstance 方法。里面有一些不需要的行为。你可以

  1. 使用上面链接中的信息抑制其行为
  2. 创建默认(包)或 protected setInstance 方法来替换测试期间返回的对象
  3. 理想情况下,从单例实例束缚转向 DI。这样的代码更容易测试。

关于java - Powermock ExceptionInInitializerError 与 Junit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46755197/

相关文章:

java - 如何解析原始cookie

java - 如何查找结果集的磁盘使用情况?

java - 什么是 JSP 上下文?

java - 在 Spring 中配置 ObjectMapper

java - 注入(inject) Spring 存储库及其提供的类

java - 使用 Junit 比较数组元素

java - 将 Excel 文件 (xls,xlsx) 转换为 PDF

java - Spring Reactive - 重用Mono值

java - 在模拟类中初始化私有(private)字段

java - JUnit 中的固定装置和文件结构