MockMVC 和 Mockito 返回状态预期为 200,但实际为 415

spring

1个回答

写回答

Mince

2025-06-28 22:15

+ 关注

JS
JS

使用 MockMVC 进行单元测试时,我们经常会遇到预期返回状态与实际返回状态不一致的情况。这是因为我们在测试过程中可能会遗漏一些关键的配置或参数设置,导致测试无法正确地模拟请求和响应。本文将介绍一个常见的错误情况,即预期返回状态为 200,但实际返回状态为 415 的情况,并提供使用 Mockito 解决这个问题的案例代码。

在单元测试中,我们经常使用 MockMVC 来模拟 HTTP 请求和响应。MockMVC 提供了一套方便的 API,可以帮助我们构建和执行 HTTP 请求,并断言返回的响应是否符合预期。然而,有时候我们会遇到一些意外情况,例如预期返回状态为 200,但实际返回状态却是 415。这种情况通常是由于请求的内容类型不正确导致的。

案例代码:

假设我们有一个 UserController 类,其中有一个 POST 接口用于创建用户。该接口接收一个 JSON 格式的请求体,并返回一个用户对象的 JSON 格式响应。我们希望使用 MockMVC 对该接口进行单元测试,验证它的功能是否正常。

Java

@RestController

public class UserController {

@PostMapping("/users")

public User createUser(@RequestBody User user) {

// 省略业务逻辑

return user;

}

}

为了进行单元测试,我们需要创建一个 UserControllerTest 类,并使用 MockMVC 对 UserController 类进行测试。我们希望测试的场景是,当我们发送一个有效的 JSON 请求体时,UserController 正确地解析并返回相应的用户对象。我们预期返回的状态码应为 200。

Java

@RunWith(SpringRunner.class)

@WebMvcTest(UserController.class)

public class UserControllerTest {

@Autowired

private MockMvc mockMvc;

@Test

public void testCreateUser() throws Exception {

// 准备测试数据

User user = new User("John", "Doe");

// 执行 POST 请求

mockMvc.perform(post("/users")

.contentType(MediaType.APPLICATION_JSON)

.content(new ObjectMapper().writeValueAsString(user)))

.andExpect(status().isOk())

.andExpect(JSonPath("$.firstName", is("John")))

.andExpect(JSonPath("$.lastName", is("Doe")));

}

}

在上面的测试代码中,我们使用 MockMVC 的 perform() 方法来执行 POST 请求,并使用 contentType() 方法设置请求的内容类型为 APPLICATION_JSON。然后,我们使用 content() 方法将用户对象转换为 JSON 字符串,并将其作为请求体传递给 perform() 方法。最后,我们使用 andExpect() 方法来断言返回的状态码是否为 200。

然而,当我们运行上述测试代码时,会发现测试失败,实际返回的状态码是 415。这是因为在默认情况下,MockMVC 使用的是 Spring MVC 的默认配置,会对请求的内容类型进行严格的匹配。如果请求的内容类型与接口方法的参数类型不匹配,就会返回状态码 415,表示不支持的媒体类型。

解决方案:

为了解决这个问题,我们可以使用 Mockito 来模拟请求和响应,并手动设置请求的内容类型。Mockito 是一个强大的 Java 单元测试工具,可以帮助我们模拟对象和行为,并进行断言验证。

在上述示例代码中,我们可以使用 Mockito 的 @Mock 注解来模拟 HttpServletRequest 和 HttpServletResponse 对象,并使用 @InjectMocks 注解将它们注入到 UserController 中。然后,我们可以在测试方法中手动设置请求的内容类型,以避免默认的严格匹配。

Java

@RunWith(MockitoJUnitRunner.class)

public class UserControllerTest {

@InjectMocks

private UserController userController;

@Mock

private HttpServletRequest request;

@Mock

private HttpServletResponse response;

@Test

public void testCreateUser() throws Exception {

// 准备测试数据

User user = new User("John", "Doe");

// 设置请求的内容类型为 APPLICATION_JSON

when(request.getcontentType()).thenReturn(MediaType.APPLICATION_JSON_VALUE);

// 执行创建用户的方法

User result = userController.createUser(user);

// 验证返回的用户对象是否符合预期

assertEquals("John", result.getFirstName());

assertEquals("Doe", result.getLastName());

}

}

在上述修改后的测试代码中,我们使用 Mockito 的 when() 方法和 getcontentType() 方法模拟了请求的内容类型,并设置其返回值为 APPLICATION_JSON_VALUE。这样,当 UserController 的 createUser() 方法被调用时,将会正确地解析请求,并返回预期的用户对象。通过手动设置请求的内容类型,我们避免了默认的严格匹配,确保了测试的正确性。

:

本文介绍了使用 MockMVC 进行单元测试时,预期返回状态与实际返回状态不一致的情况,并提供了使用 Mockito 解决这个问题的案例代码。在单元测试中,我们常常会遇到各种意外情况,需要注意配置和参数设置。通过合理地使用 MockMVC 和 Mockito,我们可以更好地进行单元测试,提高代码的质量和可靠性。

举报有用(4)分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号