【问题标题】:PowerMockito spy calling real method gets NullPointerExceptionPowerMockito spy 调用真实方法获取 NullPointerException
【发布时间】:2019-02-13 07:56:11
【问题描述】:

从spy类调用真实方法service.listObjectA("abc")时,出现空指针异常,指向原类的ArrayList初始化行List<ObjectASummary> objAList = new ArrayList<>()

我在 IDE 中对此进行了调试,并获取了 screenshot 的堆栈跟踪详细信息。
它说Method threw 'java.lang.NullPointerException' exception. Cannot evaluate net.bytebuddy.description.type.TypeDescription$ForLoadedType.toString()

我还被告知要粘贴堆栈跟踪,所以就在这里。

java.lang.NullPointerException
    at com.myorg.myproject.service.ObjectAService.listObjectA(ObjectAService.java:181)
    at com.myorg.myproject.test.testcases.api.unit.ObjectAServiceTest.testListObjectA(ObjectAServiceTest.java:95)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
    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:298)
    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:218)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
    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:136)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:117)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    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)

ObjectAService.java 第 181 行: List<ObjectASummary> objAList = new ArrayList<>();

这是要测试的类:

public class ObjectAService {

    public ObjectAService(ObjectADataProvider dataProvider, WorkRequestService workRequestService, ObjectBServiceInterface objBService, ObjectCFactory objCFactory, SWConfig swConfig) {
        //constructor
    }

    @Override
    public List<ObjectASummary> listObjectA(String s) {           

        List<ObjectASummary> objAList = new ArrayList<>();//NullPointerException thrown from this ArrayList initiation line

        /*
        Code to query backend for the list and process them.
        The back end query client is mocked and behaviors are stubbed in the test.
        */

        return objAList;
    }
}

这是测试:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ObjectAService.class, RealmIdFactory.class})
@PowerMockIgnore({ "javax.net.ssl.*", "javax.security.*" })
public class ObjectATest {

    private SystemClient swClient;
    private ManagedInstanceService service;

    public ObjectATest() {

        service = PowerMockito.spy(new ObjectAService(null, null, null, null, new SWConfig()));
        swClient = PowerMockito.mock(SystemClient.class);
    }

    @Test
    public void testListObjectA() throws Exception {

        List<ClientSystem> systems = new ArrayList(listSize);
        for(int i = 0; i < 10; i++) {
            systems.add(new ClientSystem());
        }
        PowerMockito.doReturn(swClient).when(service,"getSystemClient");
        PowerMockito.doReturn("xxx.yyy.zzz").when(service,"getObjectAOcid", anyString());
        PowerMockito.doReturn(ObjectADetails.Status.Normal).when(service, "getClientSystemOsaStatus", any(SystemClient.class), anyInt());

        PowerMockito.when(swClient.listSystems()).thenReturn(systems);

        List<ObjectASummary> list = service.listObjectA("abc");
        assertNotNull(list);
    }
}

【问题讨论】:

  • 请在您的问题中添加堆栈跟踪。从屏幕截图中不清楚 - 发生了什么。顺便说一句,在外部系统上发布图像并将其链接添加到您的问题并不是一个好主意,因为图像将在一段时间后被删除,您的问题对于其他开发人员将变得无用,寻找类似问题的解决方案.
  • @Vusa 感谢您查看问题。添加了 Stacktrace,尽管我没有从中找到太多信息。此外,我尝试直接在问题中发布图像,但我没有足够的声誉这样做。截图是上传到堆栈溢出而不是一些外部系统。
  • ObjectAService.java:181 - 这一行的代码是什么?
  • @Vusal,它是一个数组列表的初始化,可以在第一个代码中找到sn-p.List objAList = new ArrayList();//NullPointerException throw from这个 ArrayList 起始行
  • 感谢您提供的信息。考虑到您将大量 null 值传递给 ObjectAService 的构造函数,并且您的 listObjectA 与 DB 交互(正如您在问题中所述) - 这里的 NPE 是不可避免的。但如果 NPE 确实发生在 ArrayList 创建行 - 那么您可能在 PowerMock 中发现了一些错误。

标签: java unit-testing mockito powermockito


【解决方案1】:

我不知道您为什么要使用 PowerMock,但对我来说没有用处。 PowerMock的使用非常具体,通常背后有概念的问题。

我建议您单独使用 Mockito,看看问题是否仍然存在。

如果问题消失,则将其报告给开发团队。

【讨论】:

    猜你喜欢
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多