У меня есть класс, который содержит следующие три метода:
void add(Service... objs)
void add(Collection<Service> objs)
void add(Stream<Service> objs)
Как и следовало ожидать, все они поддерживают добавление нуля или более объектов, которые могут быть указаны индивидуально или как часть массива , коллекция или поток. Первые два варианта создают поток из своих аргументов и передают их третьему варианту, который фактически выполняет добавление.
При тестировании объекта, который использует этот класс, я создал макет объекта Mockito для представления экземпляра. этого класса, используя аннотацию Spring @MockBean. В отладчике я вижу, что тестируемый объект содержит фиктивный объект и что ожидаемый мной вызов (с одним аргументом типа Service) адресован макету. Поскольку метод, который следует вызвать, является первым вариантом (вариант varargs), и я знаю, что параметры varargs немного сложны, я закодировал тест, чтобы проверить, что макет вызывается с правильным параметром, следующим образом:
ArgumentCaptor<Service> captor = ArgumentCaptor.forClass(Service.class);
verify(theMock).add(captor.capture());
assertThat(captor.getAllValues()).containsExactly(expectedService);
Однако, когда я запускаю этот код, утверждение не выполняется, потому что список, возвращаемый captor.getAllValues (), содержит не службу, а поток: сообщение об ошибке говорит:
java.lang.AssertionError:
Expecting:
<[java.util.stream.ReferencePipeline$Head@2cfe272f]>
to contain exactly (and in same order):
<[com.xxx.data.Service@37c5]>
but some elements were not found:
<[com.xxx.data.Service@37c5]>
and others were not expected:
<[java.util.stream.ReferencePipeline$Head@2cfe272f]>
Когда я запустите код в отладчике, я вижу, что вызов от тестируемого объекта к add(Service...)
вызывает реальную реализацию; это вызывает add(Stream<Service>)
, и это тот вызов, который перехватывается имитатором. Это объясняет, почему я вижу сбой, но я не понимаю, почему макет не может перехватить исходный вызов, или что я могу сделать, чтобы заставить его это сделать.