когда я выполнял синхронизацию, я писал модульные тесты, имитирующие часть персистентности, и проверял поведение вызывающего. Вот пример того, что я обычно делал:
@Mock
private OfferPersistenceServiceImpl persistenceService;
@Inject
@InjectMocks
private OfferServiceImpl offerService;
...
@Test
public void createInvalidOffer() {
offer = new Offer(null, null, null, null, null, 4, 200D, 90D);
String expectedMessage = Offer.class.getName() + " is not valid: " + offer.toString();
Mockito.when(persistenceService.create(offer)).thenThrow(new IllegalArgumentException(expectedMessage));
Response response = offerService.create(offer);
Mockito.verify(persistenceService, Mockito.times(1)).create(offer);
Assert.assertEquals(INVALID_INPUT, response.getStatus());
String actualMessage = response.getEntity().toString();
Assert.assertEquals(expectedMessage, actualMessage);
}
Но теперь я влюбился в Vertx.io (в котором я новичок) и хочу быть асинхронным. Отлично. Но у Vertx есть обработчики, поэтому новый компонент персистентности для имитации выглядит так:
...
mongoClient.insert(COLLECTION, offer, h-> {
...
});
Итак, я догадываюсь, как имитировать обработчик h
для тестирования класса, который использует этот mongoClient
, или даже если это правильный способ тестирования с Vertx.io. Я использую vertx.io 3.5.0
, junit 4.12
и mockito 2.13.0
. Спасибо.
Обновление. Я попытался последовать совету tsegimond, но не могу понять, как Answer
и ArgumentCaptor
Mockito могут мне помочь. Вот что я пробовал до сих пор. Использование ArgumentCaptor
:
JsonObject offer = Mockito.mock(JsonObject.class);
Mockito.when(msg.body()).thenReturn(offer);
Mockito.doNothing().when(offerMongo).validate(offer);
RuntimeException rex = new RuntimeException("some message");
...
ArgumentCaptor<Handler<AsyncResult<String>>> handlerCaptor =
ArgumentCaptor.forClass(Handler.class);
ArgumentCaptor<AsyncResult<String>> asyncResultCaptor =
ArgumentCaptor.forClass(AsyncResult.class);
offerMongo.create(msg);
Mockito.verify(mongoClient,
Mockito.times(1)).insert(Mockito.anyString(), Mockito.any(), handlerCaptor.capture());
Mockito.verify(handlerCaptor.getValue(),
Mockito.times(1)).handle(asyncResultCaptor.capture());
Mockito.when(asyncResultCaptor.getValue().succeeded()).thenReturn(false);
Mockito.when(asyncResultCaptor.getValue().cause()).thenReturn(rex);
Assert.assertEquals(Json.encode(rex), msg.body().encode());
и используя Answer
:
ArgumentCaptor<AsyncResult<String>> handlerCaptor =
ArgumentCaptor.forClass(AsyncResult.class);
AsyncResult<String> result = Mockito.mock(AsyncResult.class);
Mockito.when(result.succeeded()).thenReturn(true);
Mockito.when(result.cause()).thenReturn(rex);
Mockito.doAnswer(new Answer<MongoClient>() {
@Override
public MongoClient answer(InvocationOnMock invocation) throws Throwable {
((Handler<AsyncResult<String>>)
invocation.getArguments()[2]).handle(handlerCaptor.capture());
return null;
}
}).when(mongoClient).insert(Mockito.anyString(), Mockito.any(),
Mockito.any());
userMongo.create(msg);
Assert.assertEquals(Json.encode(rex), msg.body().encode());
И вот запуталась. Есть ли способ издеваться над AsyncResult
, чтобы он возвращал false на succeed()
?