Java Mockito验证一个方法在spy之后被调用一次,尽管它从未被调用
我有一个单元测试,一开始就发现了一个奇怪的问题Java Mockito验证一个方法在spy之后被调用一次,尽管它从未被调用,java,junit,mockito,Java,Junit,Mockito,我有一个单元测试,一开始就发现了一个奇怪的问题 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";
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,orgId, eventId, scenario, orgFlag);
除了模拟我的对象,我什么也没做,然后我验证mock方法从未被调用
但结果给了我:
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)
我想知道是否还有其他地方调用此方法,因此我尝试删除代码
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
然后结果被传递,证明实际上没有其他地方调用此方法
但是为什么mockito会给我这个结果呢
我试过下面的测试,但它通过了
{
//test mock
Date mockD = spy(new Date());
when(mockD.getTime())
.thenReturn(1l)
.thenThrow(new RuntimeException("mock ex"));
verify(mockD, never()).getTime();
}
-------------------方法requestTargetDCNFromGSLServer
的原始实现如下--------------
你在嘲弄间谍,所以你应该遵循嘲弄的顺序:
doReturn(buildMockSuccessGSLRespMsg(GSLResponse.ORG_FALG_GSL_INPUT, GSLRetDCN))
.doThrow(new GSLClient.GSLInvokeTimeoutException("Mock GSL timeout"))
.when(gslClient).requestTargetDCNFromGSLServer(
mockGSLBizSeqNo,orgId, eventId, scenario, orgFlag);
在您当前的情况下,您在模拟时调用了一个真正的实现,这就是为什么会出现错误。当您使用开始配置时,预计Mockito可以在
When
方法中“保护”间谍的实际方法调用。即使您的解决方案可能有所帮助,我也无法重现此问题中的问题。我假设还有另一个问题。我尝试了另一个模拟对象Date
,并模拟了它的getTime()
方法,但没有问题。所以,对于我的紧急需要,我如何解决我的问题时,嘲笑,你也能指出为什么,因为我是新的莫基托。然后应该讨论问题的原因,我的意思是为什么我对Date
Ok使用相同的方法时没有问题,但我会坚持测试您的代码,因为它可能包含一些微妙的细节。在我的更改后,您是否会收到相同的错误?@MaciejKowalski,是的,我将我的模拟方法删除到您的测试代码中,它可以工作,但我必须模拟第二个返回结果,因此它不是等效的,请更新您的答案。并指出两者的区别。非常感谢。“好了,”解决方案补充道。您只是从前面而不是从后面堆叠。您能否提供requestTargetDCNFromGSLServer
方法的声明?在界面和类中都有。@SergheyBishyr,已在问题中显示。并且没有接口,此方法在抽象类中声明GSLClient
doReturn(buildMockSuccessGSLRespMsg(GSLResponse.ORG_FALG_GSL_INPUT, GSLRetDCN))
.doThrow(new GSLClient.GSLInvokeTimeoutException("Mock GSL timeout"))
.when(gslClient).requestTargetDCNFromGSLServer(
mockGSLBizSeqNo,orgId, eventId, scenario, orgFlag);