未完成的验证,在编写 JUnit 测试用例时缺少验证(模拟)的方法调用



我正面临

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at systemservice.test1.SysParamsBuilderTest.testBuildProcessingInfoIf3(SysParamsBuilderTest.java:241)

我已经检查了所有参数和正在传递以进行验证的对象,但无法弄清楚导致上述异常的原因

我试图测试的条件,

if( request.getProcessType() == IPRequest.IPREQUEST_TYPE_DE )
{
LookInfoIf rdr = new MCLLookInfoReader();
String origAnatomy = accessor.getValue(AttributeRepNames.ANATOMY_INFO.getTagName());
String origView = accessor.getValue(AttributeRepNames.VIEW_INFO.getTagName());
String origPatSize = accessor.getValue(AttributeRepNames.PATIENT_SIZE.getTagName());
String mclPatSize = getMclPatientSize(origPatSize);
String boneLook = rdr.getDefaultLook(origAnatomy,origView,core.MCLConstants.IMAGETYPEBONETAG,mclPatSize);
String tissueLook = rdr.getDefaultLook(origAnatomy,origView,core.MCLConstants.IMAGETYPESOFTTISSUETAG,mclPatSize);
params.setProcessingLookBone(boneLook);
params.setProcessingLookTissue(tissueLook);
params.setAnatomy(origAnatomy);
params.setView(origView);
params.setPatientSize(origPatSize);
}

测试用例

@Test
public void testBuildProcessingInfoIf3() throws Exception
{
IPRequest req=new IPRequest(1);//value of IPRequest.IPREQUEST_TYPE_DE
IPSysParams iPSysParams = Mockito.mock(IPSysParams.class);
PowerMockito.whenNew(IPSysParams.class).withNoArguments().thenReturn(iPSysParams);
TagAccessor accessor=Mockito.mock(TagAccessor.class);
MCLLookInfoReader rdr=Mockito.mock(MCLLookInfoReader.class);
PowerMockito.whenNew(MCLLookInfoReader.class).withNoArguments().thenReturn(rdr);
Mockito.when(accessor.getValue(AttributeRepNames.ANATOMY_INFO.getTagName())).thenReturn("ANATOMY_INFO");
Mockito.when(accessor.getValue(AttributeRepNames.VIEW_INFO.getTagName())).thenReturn("VIEW_INFO");
Mockito.when(accessor.getValue(AttributeRepNames.PATIENT_SIZE.getTagName())).thenReturn("PATIENT_SIZE");
Mockito.when(rdr.getDefaultLook("ANATOMY_INFO","VIEW_INFO",core.MCLConstants.IMAGETYPEBONETAG,"All")).thenReturn("boneLook");
Mockito.when(rdr.getDefaultLook("ANATOMY_INFO","VIEW_INFO",core.MCLConstants.IMAGETYPESOFTTISSUETAG,"All")).thenReturn("tissueLook");
sysParamsBuilder.buildProcessingInfo(req, info);
String origAnatomy=accessor.getValue(AttributeRepNames.ANATOMY_INFO.getTagName());
assertEquals("ANATOMY_INFO",origAnatomy);
String origView=accessor.getValue(AttributeRepNames.VIEW_INFO.getTagName());
assertEquals("VIEW_INFO",origView);
String origPatSize=accessor.getValue(AttributeRepNames.PATIENT_SIZE.getTagName());
assertEquals("PATIENT_SIZE",origPatSize);
PowerMockito.verifyPrivate(sysParamsBuilder).invoke("getMclPatientSize",origPatSize);//line 241
String boneLook=rdr.getDefaultLook("ANATOMY_INFO","VIEW_INFO",core.MCLConstants.IMAGETYPEBONETAG,"All");
assertEquals("boneLook",boneLook);
String tissueLook=rdr.getDefaultLook("ANATOMY_INFO","VIEW_INFO",core.MCLConstants.IMAGETYPESOFTTISSUETAG,"All");
assertEquals("tissueLook",tissueLook);
Mockito.verify(iPSysParams).setProcessingLookBone(boneLook);//line 244
Mockito.verify(iPSysParams).setProcessingLookTissue(tissueLook);
// fill the Anatomy View accrodingly
Mockito.verify(iPSysParams,Mockito.times(1)).setAnatomy(origAnatomy);
Mockito.verify(iPSysParams).setView(origView);
Mockito.verify(iPSysParams).setPatientSize(origPatSize);
}

堆栈跟踪

org.mockito.exceptions.misusing.UnfinishedVerificationException: 
Missing method call for verify(mock) here:
-> at systemservice.test1.SysParamsBuilderTest.testBuildProcessingInfoIf3(SysParamsBuilderTest.java:241)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
at systemservice.test1.SysParamsBuilderTest.testBuildProcessingInfoIf3(SysParamsBuilderTest.java:244)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
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:294)
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:122)
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)

我以同样的方式完成了其他测试用例并且它已经工作了,但我不知道为什么它在这里不起作用,而且所有方法都是公开的。 请帮我弄清楚,提前谢谢

从异常消息来看,问题是这一行:

PowerMockito.verifyPrivate(sysParamsBuilder).invoke("getMclPatientSize",origPatSize);//line 241

使用谷歌搜索powermockito verifyprivate not working我找到了以下页面:https://groups.google.com/forum/#!topic/powermock/CEdP24sb_HY

简而言之,如果你想使用PowerMockito来监视你的对象,你一定不能这样做

SysParamsBuilder sysParamsBuilder = Mockito.spy(new SysParamsBuilder(...));

相反,你需要做

SysParamsBuilder sysParamsBuilder = PowerMockito.spy(new SysParamsBuilder(...));

否则,如果您尝试使用 PowerMockito 验证私有方法调用,您将获得您看到的异常。

我不明白这里的mockito错误;但我的答案是不同的方向:不要像这样验证。

你在这里遵循一个几乎反的模式:你想对生产代码中发生的几乎每一个调用使用模拟/验证。这意味着生产代码中的细微更改将始终直接影响单元测试。即使方法的"协定"保持不变,当您使用这种验证方式时,单元测试也会很快中断。

我的建议:与其验证一个对象是否看到很多 setter 调用,不如执行以下操作:

Params expectedParams = ... 
Params actualParams = underTest.whatever();
assertThat(actualParams, is(expectedParams));

如果简单的"等于"检查is匹配器正在做的hamcrest在这里不起作用;你仍然可以创建自己的匹配器。

换句话说:不要在单元测试中"微管理"你的生产代码。

专注于编写允许测试的代码,而不关心内部如何完成工作。相反,请检查您的方法产生的"输出"!

示例:假设你像上面一样对一些参数对象进行了所有模拟验证;但最后,你的方法返回了一些其他参数对象......那么你的单元测试可能通过;但是整个方法是错误的,因为它给了你错误的结果。

来自您的错误消息:

错误可能会出现,因为您验证了以下任一方法:final/private/equals()/hashCode()方法。 这些方法无法存根/验证。

因此,请检查是否有任何此方法

Mockito.verify(iPSysParams).setProcessingLookBone(boneLook);
Mockito.verify(iPSysParams).setProcessingLookTissue(tissueLook);
Mockito.verify(iPSysParams,Mockito.times(1)).setAnatomy(origAnatomy);
Mockito.verify(iPSysParams).setView(origView);
Mockito.verify(iPSysParams).setPatientSize(origPatSize);

final.

最新更新