尝试测试调用 @Async 方法的控制器时出现“断言错误:异步未启动”

问题描述

我遇到了与 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());
}

测试没有变化!

希望这对某人有帮助!