Issue
I've one simple question. I've got two classes
XMessage
and YMessage
. These two classes are the sub class of ZClass
.
These messages are published from a PublisherService
with method
public void publish(ZClass message, Properties props){
// some lowlevel stuff.
// note that method is taking ZClass as an arg.
}
According to my logic XMessage
is sent many times while YMessage
is sent only once in one test.
Let's say XMessage
is supposed to be sent 4 times where YMessage
is sent 1 time. I would assume below code would work.
ArgumentCaptor<XMessage> xCaptor = ArgumentCaptor.forClass(XMessage.class);
verify(publisherService, times(4)).sendMessage(isA(XMessage.class),any());
verify(publisherService, times(1)).sendMessage(isA(YMessage.class),any());
verify(publisherService, times(4)).sendMessage(xCaptor,any());
However it fails with captor and the captor has 5 values.
What am I doing wrong?
Thanks in advance.
Solution
This is a known issue in Mockito. The issue is that ArgumentCaptor
is not type aware.
See https://github.com/mockito/mockito/issues/565
This is open from 2016 and still not fully fixed so I would just did some workaround around it.
You can capture all of the arguments and then instanceof
just the ones you need.
ArgumentCaptor<ZClass> zCaptor = ArgumentCaptor.forClass(ZClass.class);
Mockito.verify(publisherService, times(5)).publish(zCaptor.capture(), ArgumentMatchers.<Properties>any());
List<XMessage> xMessages = zCaptor.getAllValues()
.stream()
.filter(arg -> arg instanceof XMessage)
.map(arg -> (XMessage) arg)
.collect(Collectors.toList());
Answered By - Pavel Polivka
Answer Checked By - Pedro (JavaFixing Volunteer)