使用Mockito模拟接口返回NullPointerException

问题描述 投票:0回答:1

我试图为一个项目创建单元测试。我面临一个问题,因为当我尝试控制接口(模拟)的结果时。当代码获取返回NullPointerException的Interface变量时。

首先,我尝试在测试类(ClassA)中使用@Override方法,但该方法无效。之后,我尝试模拟接口对象并使用Mockito.When()。tehnReturn();

来控制命令区。

我将把我的代码放在这里,我读了一些解决方案,但没有用。

我的界面:

    @FunctionalInterface
    public interface Interface {
        UpdateXResponse process(UpdateXRequest request) throws Exception;
    }

我要测试的课程:

    @Service(ClassA.class)
    public class ClassA extends VService implements UpdateX {

        @Reference
        @Inject
        private Interface interface;

        @Inject
        public ClassA(...) {...}

        @Override
        public UpdateXResponse process(UpdateXRequest request) throws Exception {
            UpdateXResponse response = initResponse(context, request, new UpdateXResponse());
            UpdateXInput input = request.getInput();
            UpdateXOutput output = new UpdateXOutput();
            response.setOutput(output);

            try {
                firstMethodCall(...);

            } catch (Exception t) {
                throwCorrectException(t, logger);
            }
            return response;
        }

        private void firstMethodCall(...) throws Exception {
            TypeF typeF = callInterfaceMethod(...);
            ...
        }

        /**
         * Orchestrates Interface service
         */
        protected TypeF callInterfaceMethod(...) {
            ...
            request.setInput(input);
            request.setHeader(header);

            InterfaceResponse response = interface.process(request); // LINE ERROR - In this step interface is NULL when the test get this

            return response;
        }
    }

最后是我的课堂测试:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(value = {ClassA.class,Interface.class} )
    public class WithPowerMockUnitTest{

        @InjectMocks
        private ClassA classA;

        private Interface interface;

        @Before
        public void setUp() throws Exception {
            InterfaceRequest InterfaceRequest = createInterfaceRequest();
            InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();

            Interface = Mockito.mock(Interface.class);
            when(Interface.process(Mockito.any(InterfaceRequest.class))).thenReturn(serviceUnavailableResponse);  
        }

        @Test
        public void testh() throws SOAException {
            InterfaceResponse res = interface.process(Mockito.any(InterfaceRequest.class)); // There all run ok. The interface is not null and return what i expected.
            System.out.println("RES "+res);
        }
        @Test
        public void test() {
            assertNotNull(classA);  // not null
            assertNotNull(interface); // not null
        }

        @Test
        public void newTest() throws Exception {

            InterfaceRequest InterfaceRequest = createInterfaceRequest();
            InterfaceResponse serviceUnavailableResponse = createInterfaceResponse();

            UpdateXResponse response = ClassA.process(updateXRequest()); // PROBLEM!! When that get the LINE ERROR the interface is null! WHY?      
        }
    }

我在存在问题的行中添加了一些评论。


    public interface A{
        Response process(Request r) throws Exception;
    }

    public class B{

    private Class_That_Override_Interface_method  ctoim;

        public Response function(){
          X res = method_B();
        }
        protected X method_B(){
          response res = ctoim.process(request); // That ctoim is always NULL when the test get that line/call
        }

    }

谢谢

interface mocking mockito powermock
1个回答
0
投票

您缺少@Mock变量上的Interface注释。因此,该模拟不会注入到您的classA中,并且newTest()将失败。 (在这种情况下,请从Interface = Mockito.mock(Interface.class);方法中删除setUp。)>

可替代地删除@InjectMocks批注,并手动将您的模拟传递到构造函数中,以创建要测试的类。


对于此特定情况(假设其与上一个问题不同)似乎没有必要涉及PowerMockito。因此,除非您遗漏了一些相关的部分,否则您最好只使用MockitoJUnitRunner


Ps .:还记得我上次对compilable示例所说的话吗?

  • interface是关键字,不能用于变量。
  • 您还应该始终编写相同的变量(而不是Interfaceinterface / classAClassA
  • 并且如果您还没有阅读它,请查看有关minmal reproducible examples的帮助部分。


编辑:

我不得不提到interface.process(Mockito.any(InterfaceRequest.class));中的testh()行实际上是无效的语法。您只应将ArgumentMatchers用于模拟方法的参数。

使用MockitoAnnotations.initMocks(this);时,也请考虑将MockitoAnnotations.initMocks(this);添加到setUp方法中。

© www.soinside.com 2019 - 2024. All rights reserved.