早上好,
我已经为此苦苦挣扎了一天,我无法回避我做错的事情。预先感谢您的帮助!
我有一种测试方法:
@Test
public void shouldReturnConflictWhenPlayerAlreadyRegistered()
{
CompletableFuture<Void> failFlow = new CompletableFuture<>();
failFlow.completeExceptionally(new CompletionException(new PlayerNameAlreadyRegisteredException(
"Player already registered")));
when(mockedWhackAMoleService.register(any(String.class))).thenReturn(failFlow);
given().params("name", "dan")
.standaloneSetup(registrationResource)
.when()
.post("/players")
.then()
.statusCode(HttpStatus.CONFLICT.value());
}
前提很简单:执行到/players
的POST(在register
类上调用RegistrationResource
时),模拟的mockedWhackAMoleService.register
方法返回一个CompletableFuture,该异常完成。使用调试器逐步进行测试,显示对mockedWhackAMoleService.register(...)
的调用确实确实触发了exceptionally
类中的RegistrationResource
分支。
为完整起见,这是被测类RegistrationResource
的代码:
@PostMapping
public CompletionStage<ResponseEntity<Void>> register(@RequestBody String name)
{
logger.info("Registering player {}", name);
return whackAMoleService.register(name).thenApply(ResponseEntity::ok).exceptionally(t -> {
logger.error(t.getCause().getMessage());
if (t.getCause() instanceof PlayerNameAlreadyRegisteredException)
{
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}
else
{
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
});
}
如果我运行服务器并在register
上开机自检到RegisterResource
方法,并尝试两次注册同一播放器,我确实会收到409响应-如预期。
但是,运行测试时,then().statusCode(HttpStatus.CONFLICT.value())
失败,因为它收到200,而不是预期的409!
知道我在做什么错吗?
非常感谢,丹
我找到了答案!事实证明,由于控制器和服务是异步的,因此单元测试没有等待正确的响应:https://stackoverflow.com/a/46912047/2124631