MockMVC 对异步服务执行后期测试

Cla*_*omo 5 asynchronous mocking spring-mvc mockito async-await

我需要测试一个调用异步服务的控制器。

控制器代码

@RequestMapping(value = "/path", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Result> massiveImport(HttpServletRequest request) {
    try {
        service.asyncMethod(request);
    } catch (Exception e) {
        e.printStackTrace();
        return new ResponseEntity<>(new Result(e.getMessage()), HttpStatus.BAD_REQUEST);
    }

    return new ResponseEntity<>(new Result(saveContact.toString()), HttpStatus.OK);
}
Run Code Online (Sandbox Code Playgroud)

服务代码

@Async
public Future<Integer> asyncMethod(HttpServletRequest request) throws IllegalFieldValueException, Exception {
    ...
    return new AsyncResult<>(value);
}
Run Code Online (Sandbox Code Playgroud)

测试代码

MvcResult result = getMvc().perform(MockMvcRequestBuilders.fileUpload("/path/")
                           .header("X-Auth-Token", accessToken)
                           .accept(MediaType.APPLICATION_JSON))
                           .andDo(print())
                           .andReturn();
Run Code Online (Sandbox Code Playgroud)

测试没问题。但是我会在关闭测试之前等待完成异步服务。

有没有办法做到这一点?

Ren*_*ibe 5

如果您只想等待异步执行完成,请查看MvcResult。你可以用 等待它getAsyncResult()

使用您当前的代码,您只是在没有任何断言的情况下执行请求。所以测试是不完整的。对于完整的测试,需要以下两个步骤。

首先执行请求:

MvcResult mvcResult = getMvc().perform(fileUpload("/path/")
                              .header("X-Auth-Token", accessToken)
                              .accept(MediaType.APPLICATION_JSON))
                              .andExpect(request().asyncStarted())
                              .andReturn();
Run Code Online (Sandbox Code Playgroud)

然后通过asyncDispatch启动异步调度并执行断言:

getMvc().perform(asyncDispatch(mvcResult))
        .andExpect(status().isOk())
        .andExpect(content().contentType(...))
        .andExpect(content().string(...));
Run Code Online (Sandbox Code Playgroud)

  • 嗨,对我来说,`.andExpect(request().asyncStarted())` 因断言错误而失败。我错过了什么?当我简单地运行我的服务器时,异步 Futures 正在工作,但是使用 mockmvc,Futures 立即返回,而不是等待 db 调用,而只是返回一个空列表。 (2认同)