Java – Mockito verifies a method of calling onces after a spy, though it never calls.

I had a unit test and found a strange problem at the beginning

GSLClient gslClient = spy(new GSLSolaceClient());
    String orgId = "10006";
    int orgFlag = Destination.ORG_ID_INPUT_FLAG_APP;
    String eventId = "11010000";
    String scenario = "01";
    String inputDCN = "A00";
    String GSLRetDCN = "FT0";

    //mock
    when(gslClient.requestTargetDCNFromGSLServer(mockGSLBizSeqNo,orgId,eventId,scenario,orgFlag))
            .thenReturn(buildMockSuccessGSLRespMsg(GSLResponse.ORG_FALG_GSL_INPUT,GSLRetDCN))//success for first time
            .thenThrow(new GSLClient.GSLInvokeTimeoutException("Mock GSL timeout"));//timout for the second time

    verify(gslClient,never()).requestTargetDCNFromGSLServer(mockGSLBizSeqNo,orgFlag);

I did nothing but simulate my object, and then I verified that I never called the mock method

But the result gave me:

org.mockito.exceptions.verification.NeverWantedButInvoked: 
gSLSolaceClient.requestTargetDCNFromGSLServer(
    "MOCKGSLBIZSEQNO_GSL_CACHE_TEST","10006","11010000","01",0
);
Never wanted here:
-> at cn.webank.rmb.gsl.GSLCacheTest.test_76789232(GSLCacheTest.java:226)
But invoked here:
-> at cn.webank.rmb.gsl.GSLCacheTest.test_76789232(GSLCacheTest.java:222)


    at cn.webank.rmb.gsl.GSLCacheTest.test_76789232(GSLCacheTest.java:226)
    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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

I wanted to know if there was another place to call this method, so I tried to delete the code

when(gslClient.requestTargetDCNFromGSLServer(mockGSLBizSeqNo,GSLRetDCN))//success for first time
            .thenThrow(new GSLClient.GSLInvokeTimeoutException("Mock GSL timeout"));//timout for the second time

Then pass the result to prove that no other place is actually calling this method

But why did mockito give me this result?

I tried the following test, but it passed!

{
        //test mock
        Date mockD = spy(new Date());
        when(mockD.getTime())
                .thenReturn(1l)
                .thenThrow(new RuntimeException("mock ex"));
        verify(mockD,never()).getTime();
    }

——————-The original implementation of the requesttargetdcnfromgslserver method is like –

Message requestTargetDCNFromGSLServer(String bizSeqNo,String targetOrgId,String serviceEventId,String scenario,int orgFlag) throws RMBValidationException,RMBillegalaccessexception,GSLInvokeTimeoutException {
    System.out.println("-------------------------------------------------------requestTargetDCNFromGSLServer");//I can only see this log one time
    SysHeader msgHeader = Util.createSysHeader(bizSeqNo,bizSeqNo,SOURCESYSID);
    Destination destination = Util.createSimpleDestination(GSL_SERVICEID,GSL_SCENARIO,GSL_DCN);
    Message reqMessage = Util.createMessage(msgHeader,GSL_APPHEADER,destination,createRequestContent(targetOrgId,serviceEventId,orgFlag));
    IMessagePublisher synPublisher = getSyncpublisherInstance();
    reqMessage.setTimeToLive(Global.onlyInstance().getGslRequestTimeout());
    Message rspMessage = synPublisher.publish(reqMessage,Global.onlyInstance().getGslRequestTimeout()) ;
    if(rspMessage == null) {
        throw new GSLClient.GSLInvokeTimeoutException("Cannot recieve GSL response at "+ Global.onlyInstance().getGslRequestTimeout()+" ms");
    }else {
        return rspMessage;
    }

}

Solution

You're laughing at spies, so you should stick to this order of laughing:

doReturn(buildMockSuccessGSLRespMsg(GSLResponse.ORG_FALG_GSL_INPUT,GSLRetDCN))
    .doThrow(new GSLClient.GSLInvokeTimeoutException("Mock GSL timeout"))
    .when(gslClient).requestTargetDCNFromGSLServer(
             mockGSLBizSeqNo,orgFlag);

In your current situation, you call a real implementation during simulation, which is why you get the error When you start configuring, mockito can "protect" actual method calls on spies within the when method

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>