Java 未完成验证,在编写JUnit测试用例时缺少验证(mock)的方法调用
我正面临Java 未完成验证,在编写JUnit测试用例时缺少验证(mock)的方法调用,java,unit-testing,exception,junit,mockito,Java,Unit Testing,Exception,Junit,Mockito,我正面临 org.mockito.exceptions.misusing.UnfinishedVerificationException: Missing method call for verify(mock) here: -> at systemservice.test1.SysParamsBuilderTest.testBuildProcessingInfoIf3(SysParamsBuilderTest.java:241) 我已经检查了所有参数和要传递以验证的对象,但无法找出导
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)
我用同样的方法做了其他的测试用例,它也起了作用,但我不知道为什么它在这里不起作用,而且所有的方法都是公开的。请帮我弄清楚,提前谢谢我不理解这里的mockito错误;但我的答案是另一个方向:不要像这样验证 在这里,您遵循的几乎是反模式:您希望对生产代码中发生的几乎每个调用和任何调用使用模拟/验证。这意味着生产代码中的细微更改总是会直接影响单元测试。即使方法的“契约”保持不变,当您使用这种验证方式时,单元测试也会很快中断 我的建议是:不必验证对象是否看到大量setter调用,您可以按照以下方式执行操作:
Params expectedParams = ...
Params actualParams = underTest.whatever();
assertThat(actualParams, is(expectedParams));
如果简单的“等于”,则检查hamcrestis
匹配器正在执行的操作在这里不起作用;您仍然可以创建自己的匹配器
换句话说:不要在单元测试中“微观管理”生产代码
专注于编写允许测试的代码,而不必关心如何在内部完成事情。相反,检查方法产生的“输出”
示例:假设您像上面那样对一些params对象进行模拟验证;但最后,您的方法返回其他一些params对象。。。那么您的单元测试可能通过了;但是整个方法是错误的,因为它给了你错误的结果 从错误消息中: 出现错误可能是因为您验证了以下方法之一: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
问题是这一行:
PowerMockito.verifyPrivate(sysParamsBuilder).invoke("getMclPatientSize",origPatSize);//line 241
使用google搜索powermockito verifyprivate not working
我找到了以下页面:
简言之,如果您想使用PowerMockito监视您的对象,您不能这样做
SysParamsBuilder sysParamsBuilder = Mockito.spy(new SysParamsBuilder(...));
相反,你需要这样做
SysParamsBuilder sysParamsBuilder = PowerMockito.spy(new SysParamsBuilder(...));
否则,如果您尝试使用PowerMockito验证私有方法调用,您将看到异常。如果我不模拟参数,则该参数将为null,然后无论在何处使用该参数,该参数也将为null,我正在为无法修改的生产代码编写测试用例,因此无法更改实现以使测试更容易。我需要检查方法中发生的每一件事,这样开发人员就很容易理解该方法的目的。在这里,我只是想验证几个电话,但无法找出为什么它没有发生,而在其他地方它是有效的。好吧,那么我的答案没有多大帮助。但是为了记录:一个只“记录”代码的测试用例。。。根本不能帮助开发人员更好地理解生产代码。它实现的唯一一件事是,您可以稍后“验证”该源代码的重构版本是否正在进行相同的调用。不要欺骗自己,让自己相信编写这样乏味的测试用例有更深层次的意义,或者为任何人提供了很多附加值。这些方法都不是最终的,都是公开的。我在我的帖子中提到过,你的测试方法中的第241行和第244行是什么?例外情况提到了这两个特定的行号,我编辑了我的帖子以显示行号