Тестирование вашего кода не тривиально, хотя и не невозможно. Моя первая идея состояла в том, чтобы использовать ArgumentCaptor , который намного проще в использовании и понимании по сравнению с ArgumentMatcher . К сожалению, тест по-прежнему не проходит - причины, безусловно, выходят за рамки этого ответа, но я могу помочь, если это вас заинтересует Тем не менее я нахожу этот тестовый пример достаточно интересным для показа ( не правильное решение ):
@RunWith(MockitoJUnitRunner.class)
public class MessageServiceTest {
@Mock
private MessageDAO messageDAO = mock(MessageDAO.class);
private MessageService messageService = new MessageService();
@Before
public void setup() {
messageService.setDao(messageDAO);
}
@Test
public void testAcceptFromOffice() throws Exception {
//given
final Message message = new Message();
//when
messageService.acceptFromOffice(message);
//then
ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
verify(messageDAO, times(2)).makePersistent(captor.capture());
final List<Message> params = captor.getAllValues();
assertThat(params).containsExactly(message, message);
assertThat(params.get(0).getStatus()).isEqualTo(0);
assertThat(params.get(1).getStatus()).isEqualTo(1);
}
}
К сожалению, рабочее решение требует несколько сложного использования Ответ . Вкратце, вместо того, чтобы позволять Mockito записывать и проверять каждый вызов, вы предоставляете своего рода метод обратного вызова, который выполняется каждый раз, когда ваш тестовый код выполняет данную имитацию. В этом методе обратного вызова (в нашем примере объект MakePersistentCallback
) у вас есть доступ к обоим параметрам и вы можете изменить возвращаемое значение. Это тяжелая пушка, и вы должны использовать ее с осторожностью:
@Test
public void testAcceptFromOffice2() throws Exception {
//given
final Message message = new Message();
doAnswer(new MakePersistentCallback()).when(messageDAO).makePersistent(message);
//when
messageService.acceptFromOffice(message);
//then
verify(messageDAO, times(2)).makePersistent(message);
}
private static class MakePersistentCallback implements Answer {
private int[] expectedStatuses = {0, 1};
private int invocationNo;
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
final Message actual = (Message)invocation.getArguments()[0];
assertThat(actual.getStatus()).isEqualTo(expectedStatuses[invocationNo++]);
return null;
}
}
Пример не завершен, но теперь тест завершается успешно и, что более важно, дает сбой, когда вы почти что-либо изменили в CUT. Как видите, метод MakePersistentCallback.answer
вызывается каждый раз, когда вызывается messageService.acceptFromOffice(message)
. Внутри naswer
вы можете выполнить все необходимые проверки.
Примечание: используйте с осторожностью, поддерживая такие тесты, по меньшей мере, хлопотно.