令人沮丧。我到处看的地方,都看到了测试异步Vertx代码的示例,但是没有什么比我要测试的更接近。
被测方法将一条消息发送到事件总线。我想验证eventBus()。send()响应处理程序中正在发生的事情。
如此,我看到许多示例都在TEST ITSELF中具有eventBus()。send()方法(因此,测试事件总线的另一端-使用者)我想在.send()中测试响应处理程序
我已经在测试中尝试了Async。尝试过ArgumentCaptor。尝试使用Thread.sleep()。尝试过doAnswer()。似乎没有任何东西可以测试(a)等待被测方法中的异步eventBus()。send()调用完成,以及(b)能够验证()是否存在交互(我认为这可能必须做一下Vertx.TestContext和JUnit.Runner Context之间的区别。.
代码: 被测方法:
public void sendToEventBusAddress(RoutingContext context, String requestId, String userId) {
List<String> stuff = split(context.request().getParam("stuffToSplit"));
JsonObject eventBusMessage = new JsonObject()
.put("requestId", requestId)
.put("stuffList", new JsonArray(stuff))
.put("userId", userId);
LOGGER.info("Putting message: {} onto the EventBus at address: {}", eventBusMessage.encodePrettily(), EventBusEndpointEnum.STUFF_ACCESS.getValue());
context.vertx().eventBus().send(EventBusEndpointEnum.STUFF_ACCESS.getValue(), eventBusMessage, new DeliveryOptions().setSendTimeout(timeout), async -> {
if (async.succeeded()) {
LOGGER.info("EventBus Response: {}", async.result().body().toString());
context.response().setStatusCode(HttpStatus.SC_OK);
context.response().headers().set(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN);
context.response().end(async.result().body().toString());
} else {
LOGGER.error(errorMessage);
context.response().setStatusCode(HttpStatus.SC_BAD_REQUEST);
context.response().end(errorMessage);
}
});
}
简化的(无效的)测试用例和类:
@RunWith(VertxUnitRunner.class)
public class MyBrokenTest {
@Mock private RoutingContext routingContext;
@Mock private HttpServerRequest contextRequest;
@Mock private HttpServerResponse contextResponse;
@Mock private MultiMap responseHeaders;
@Rule public RunTestOnContext rule = new RunTestOnContext();
@Before
public void setUp(TestContext context) {
MockitoAnnotations.initMocks(this);
}
@Test
public void testOne(TestContext context) {
when(routingContext.vertx()).thenReturn(rule.vertx());
when(routingContext.request()).thenReturn(contextRequest);
when(contextRequest.getParam("stuffToSplit")).thenReturn("04MA");
when(routingContext.response()).thenReturn(contextResponse);
when(contextResponse.headers()).thenReturn(responseHeaders);
rule.vertx().eventBus().consumer(EventBusEndpointEnum.STUFF_ACCESS.getValue(), res -> {
res.reply("yo");
});
ClassUnderTest cut= new ClassUnderTest(180000);
cut.sendToEventBusAddress(routingContext, "testRequestId", "UnitTestId");
verify(contextResponse).setStatusCode(200);
}
}
我知道当前形式的测试将无法正常工作,因为被测方法会在方法内部调用eventBus()。send()方法后立即返回,因此,验证失败并显示'no互动”。
鉴于Vertx的异步特性,我不知道要如何正确验证它!
谢谢
答案 0 :(得分:0)
我是这样做的:
在带有@BeforeAll
的批注方法中,我仅部署了发送Verticle。
在@BeforeEach
处-我为给定消息创建使用者,并将消息存储到变量/集合
类似的东西:
receivedMessage = new Message[1];
eventBus.consumer("DB",
message -> {
message.reply("OK");
receivedMessage[0] = message;
});
context.completeNow();
在测试中,我验证存储的值:
client.get(8080, "localhost", "/user/" + id)
.as(BodyCodec.string())
.send(context.succeeding((response -> context.verify(() -> {
Assertions.assertEquals(expectedMessage, receivedMessage[0].body());
context.completeNow();
}))));