【问题标题】:Spring Boot returning wrong Status Code only in Unit TestSpring Boot 仅在单元测试中返回错误的状态码
【发布时间】:2018-04-05 03:43:48
【问题描述】:

我正在使用 Spring Boot 开发一个 REST API。

我有一个控制器来创建一个新用户,它在创建用户时响应 201 (CREATED)。响应没有正文内容。

使用 Postman 或任何浏览器,我得到了 201 响应。 但是当我尝试使用单元测试(Mockito)时,响应是 200。

这是我的代码:

控制器

public CompletableFuture<ResponseEntity<Void>> registerNewUser(
    @RequestBody @Valid RegisterUserDto newUser
) throws ExecutionException, InterruptedException {

  // user service return a completable future void 
  return userService.registerNewUser(newUser).thenApply(u -> new ResponseEntity<>(u, HttpStatus.CREATED));
}

当注册过程完成时,用户服务返回一个可完成的future void。

@Async
CompletableFuture<Void> registerNewUser(NewUserDto newUserDto) throws ExecutionException, InterruptedException;

然后,在我的单元测试中,我有以下代码:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class UsersControllerTest {

  @Autowired
  private MockMvc mvc;

  @Mock
  private UsersService userService;

  @InjectMocks
  private UsersControllers usersController;

  @Before
  public void init() {
    MockitoAnnotations.initMocks(this);
    this.mvc = MockMvcBuilders.standaloneSetup(usersController).build();
  }

  @Test
  public void mustCreateANewUser() throws Exception {
    NewUserDto userMock = new NewUserDto("firstname", "lastname", "login", "password");

    when(userService.registerNewUser(any(NewUserDto.class)))
      .thenReturn(CompletableFuture.completedFuture(null));

    mvc.perform(post("/api/users/new")
                    .content(TestHelpers.convertToJson(userMock))
                    .contentType(TestHelpers.getJsonMediaType()))
        .andExpect(status().isCreated());
  }
}

TestHelpers.convertToJson 和 TestHelpers.getJsonMediaType 是静态方法。

public static MediaType getJsonMediaType() {
  return new MediaType(MediaType.APPLICATION_JSON.getType(),
                       MediaType.APPLICATION_JSON.getSubtype(),
                       Charset.forName("utf8"));
}

public static String convertToJson(Object o) throws IOException {
  ObjectMapper mapper = new ObjectMapper();
  return mapper.writeValueAsString(o);
}

我不明白为什么单元测试的响应代码是 200。在我的控制者、服务或控制者建议的任何部分中,我的响应为 200 OK。

【问题讨论】:

  • 默认情况下,Spring 控制器返回 HTTP 200 OK,因此您的测试用例是正确的。
  • 我明白了!谢谢@mrkernelpanic。因为我的控制器和服务是异步的,所以我的单元测试没有等待响应,这就是我得到 200 的原因。更改了我的单元测试,现在一切正常(我将更新我的问题)

标签: java spring unit-testing


【解决方案1】:

问题是因为我的控制器和服务是异步的,所以我的单元测试没有等待正确的响应。

将我的单元测试更改为:

MvcResult result = mvc.perform(post("/api/users/new")
  .content(TestHelpers.convertToJson(registroMock))
  .contentType(TestHelpers.getJsonMediaType()))
  .andReturn();

mvc.perform(asyncDispatch(result))
   .andExpect(status().isCreated());

【讨论】:

  • 我什至无法告诉您您为我节省了多少时间,无论是在初始问题中的代码方法还是在其解决方案中。感谢分享
  • 奥布里加多罗伯托!节省了我大量的时间。似乎对异步(deferredResult/CompletableFuture)的 IT 测试没有很好的记录。
猜你喜欢
  • 2020-11-20
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2018-07-19
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
相关资源
最近更新 更多