问题描述
我遇到了与 this one 类似的问题:尝试对从服务调用 @Async
方法的控制器进行集成测试时,会发生 AssertionError: Async not started
。
这家伙提出了一些我不太明白的建议:
您必须将响应包装为 Callable 或 DeferredResult
这是我的服务方式:
@Async
@Override
public Future<String> migrateMovies() {
Collection<MetadataItem> MetadataMovies = MetadataItemService.getAllByMetadataType(MOVIE_TYPE);
Collection<Movie> movies = mapMovies(MetadataMovies);
movieService.saveMovies(movies);
return CompletableFuture.supplyAsync(() -> movies.size() + " movies migrated successfully!");
}
这是我的控制器方法:
@PostMapping("/movies")
public ResponseEntity<String> migrateMovies() throws ExecutionException,InterruptedException {
return ResponseEntity.ok(movieMigrationService.migrateMovies().get());
}
这就是我试图测试它的方式:
@Test
@WithMockUser(username = "username")
void migrateMoviesSuccessfully() throws Exception {
Collection<Movie> expectedMovies = Lists.list(new Movie(),new Movie());
when(movieService.saveMovies(anyCollection())).thenReturn(expectedMovies);
Future<String> expectedResponse =
CompletableFuture.supplyAsync(() -> expectedMovies.size() + " movies migrated successfully!");
when(movieMigrationService.migrateMovies()).thenReturn(expectedResponse);
MvcResult mvcResult = mockmvc.perform(post("/movies"))
.andExpect(request().asyncStarted())
.andReturn();
mockmvc.perform(asyncdispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().string("2 movies migrated successfully!"));
}
有人可以为我的例子具体解释一下这种包装应该如何发生吗?
我也愿意接受任何其他建议!
注意:我的应用程序正确异步运行 + 我对服务 migrateMovies()
方法的单元测试成功,只是集成测试很顽固:)
解决方法
我在发布后很快就解决了我的问题。我实际上只是将我的控制器的返回类型包装在 Callable 中 + 使用供应商作为返回语句:
@PostMapping("/movies")
public Callable<ResponseEntity<String>> migrateMovies() throws ExecutionException,InterruptedException {
return () -> ResponseEntity.ok(movieMigrationService.migrateMovies().get());
}
测试没有变化!
希望这对某人有帮助!