[英]Getting exception as, Argument(s) are different! Wanted:
@Spy
@InjectMocks
NotificationServiceImpl notificationService;
When i use like above, I am getting exception for a test as, Argument(s) are different: Wanted.当我像上面那样使用时,我得到了一个测试的例外,因为参数不同:想要。 But but while debugging control is going inside all methods and code coverage is happening.
但是,当调试控制进入所有方法并且代码覆盖发生时。
@Mock
NotificationServiceImpl notificationService;
When i use like above, I am not getting any exception, but while debugging control is not going inside a few methods its impacting the code coverage.当我像上面那样使用时,我没有得到任何异常,但是虽然调试控制没有进入一些方法,但它会影响代码覆盖率。 Could any one suggest me the proper mocking here.
任何人都可以在这里向我推荐合适的 mocking。 So that code coverage will happen as well as no exception will come.
这样代码覆盖就会发生,并且不会出现异常。 Stack Trace
堆栈跟踪
Argument(s) are different! Wanted:
cwAlarmService.raiseNotificationProcessingAlarm(
"device_id_value",
<any string>
);
-> at com.cisco.inventory.service.NotificationMonitorTest.test_run_Exception_CW_Alarm(NotificationMonitorTest.java:189)
Actual invocations have different arguments:
cwAlarmService.raiseNotificationProcessingAlarm(
"1b8722ad-0b9b-3327-98fb-5016fcf919f5",
"Exception"
);
-> at com.cisco.inventory.scheduler.NotificationMonitor$TriggerNotificationDataCollection.run(NotificationMonitor.java:100)
at com.cisco.inventory.service.NotificationMonitorTest.test_run_Exception_CW_Alarm(NotificationMonitorTest.java:189)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
and this is the test这是测试
@Test
public void test_run_Exception_CW_Alarm() throws IOException, InterruptedException {
List<DeviceDetails> deviceDetailsList = new ArrayList<>();
DeviceDetails deviceDetails = new DeviceDetails();
deviceDetails.setDeviceId(ConstantsTest.DEVICE_ID_VALUE);
deviceDetails.setCollectionStatus(Constants.COMPLETED);
deviceDetails.setType("abc");
deviceDetails.setIP("10.58");
deviceDetailsList.add(deviceDetails);
Mockito.when(inventoryDao.getAllDeviceDetails()).thenReturn(deviceDetailsList);
Mockito.when(inventoryDao.getDeviceDetails(Mockito.any())).thenReturn(deviceDetails);
NotificationData notificationData = getNotificationData();
notificationData.setNotificationProcessingStatus(Constants.INIT);
notificationData.setDeviceId("1b8722ad");
Mockito.when(inventoryDao.getValidNotificationToBeProcessed(Mockito.any())).thenReturn(notificationData);
notificationData.setNotificationProcessingStatus(Constants.PROCESSING);
notificationData.setIsAlarm(Boolean.TRUE);
List<StringPair> list = populateSVOModelPathStringPairs();
StaticList.ModelPathMapData modelPathMapData = new StaticList.ModelPathMapData();
modelPathMapData.setName(Constants.GET_QUERY_MAP_FOR_SVO);
modelPathMapData.setModelPaths(list);
StaticList staticList = new StaticList();
staticList.setModelPathMap(modelPathMapData);
Optional<StaticList> staticListOptional = Optional.of(staticList);
Mockito.when(inventoryDao.findStaticListByID(Constants.SVO)).thenReturn(staticListOptional);
Mockito.when(inventoryDao.saveNotificationProcessingStatus(Mockito.any(),Mockito.any())).thenReturn(notificationData);
Mockito.doThrow(new RuntimeException("Exception")).when(notificationService).checkAndHandleDeleteNotifications(notificationData);
notificationMonitor.run();
Mockito.verify(cwAlarmService, Mockito.timeout(1000)).raiseNotificationProcessingAlarm(eq(ConstantsTest.DEVICE_ID_VALUE), Mockito.anyString());
}
TL;DR TL;博士
While mocking the methods of a spied object use doReturn(...).when(...)
instead of when(...).thenReturn(...)
虽然 mocking 间谍 object 的方法使用
doReturn(...).when(...)
而不是when(...).thenReturn(...)
Longer explanation更长的解释
Although in Mockito
the mocks and spies looks similar, there are some important differences.尽管在
Mockito
中,模拟和间谍看起来很相似,但还是有一些重要的区别。
@Mock
stubs all the methods. @Mock
存根所有方法。 The methods do nothing and return null
by default.null
。@Spy
does not stub anything unless it is told to. @Spy
除非被告知,否则不会存根任何东西。 It invokes the real methods of the spied object by default. There is another important implementation difference:还有另一个重要的实现差异:
when(obj.someMethod(...)).thenReturn(value)
- invokes the method someMethod
and then stubs the method. when(obj.someMethod(...)).thenReturn(value)
- 调用方法someMethod
然后存根该方法。doReturn(value).when(obj).someMethod(...)
- does not invoke the method someMethod
and stubs it right away. doReturn(value).when(obj).someMethod(...)
- 不调用方法someMethod
并立即存根。 These two approaches have similar effect while stubbing mocks.这两种方法在存根模拟时具有相似的效果。 But in case of spies calling the real method of a real object can lead to unwanted side effects.
但如果间谍调用真正的 object 的真正方法,可能会导致不必要的副作用。
So when you are using @Spy
with when(...).thenReturn(...)
there are some hidden side effects, which in your particular case result in generating an actual UUID
instead of returning the dummy value "device_id_value"
.因此,当您将
@Spy
与when(...).thenReturn(...)
一起使用时,会有一些隐藏的副作用,在您的特定情况下会导致生成实际的UUID
而不是返回虚拟值"device_id_value"
。
This also explains why your unit test works properly while using @Mock
.这也解释了为什么您的单元测试在使用
@Mock
时可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.