以下是mock mvc不支持spring boot异常处理程序的原因,然后是建议和修复。
理性摘录
Spring Boot的错误处理是基于Servlet容器错误
导致 ERROR 分派到 ErrorController 的映射。
然而,MockMvc 是无容器测试,因此没有 Servlet 容器
异常只是冒泡而没有任何东西可以阻止它。
因此 MockMvc 测试根本不足以测试错误响应
通过 Spring Boot 生成。我认为你不应该
测试 Spring Boot 的错误处理。如果您要自定义它
您可以编写 Spring Boot 集成测试的方式(使用实际的
容器)来验证错误响应。然后针对 MockMvc 测试重点
全面测试 Web 层,同时期待出现异常
向上。
这是典型的单元测试与集成测试的权衡。你做单位
即使他们没有测试所有内容,也要进行测试,因为它们会为您提供更多
控制并跑得更快。
推荐摘录
我们如何使用默认的 spring-boot 编写错误条件测试
那么 JSON 响应呢?
@xak2000 罗森已经介绍过这一点,但我想给你一个
直接回答。如果你真的想测试的精确格式
错误响应,那么您可以使用集成测试
@SpringBootTest 配置了 DEFINED_PORT 或 RANDOM_PORT web
环境和 TestRestTemplate。
完整详细信息请参见此处https://github.com/spring-projects/spring-boot/issues/7321 https://github.com/spring-projects/spring-boot/issues/7321
Fix
这里是使用 Spring Boot 测试的稍微不同的错误验证。
import org.json.JSONException;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(classes = DemoApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ModelControllerTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void import_invalidRequest_notImported() throws JSONException {
String expected = "{\"status\":400,\"error\":\"Bad Request\",\"message\":\"JSON parse error: Unrecognized token 'Invalid': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'Invalid': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\\n at [Source: (PushbackInputStream); line: 1, column: 8]\",\"path\":\"/import\"}";
String invalidJson = "Invalid";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(invalidJson, headers);
ResponseEntity<String> response = restTemplate.exchange("/import", HttpMethod.POST, entity, String.class);
assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());
assertEquals(MediaType.APPLICATION_JSON, response.getHeaders().getContentType());
JSONAssert.assertEquals(expected, response.getBody(), false);
}
}
参考这里https://mkyong.com/spring-boot/spring-rest-integration-test-example/ https://mkyong.com/spring-boot/spring-rest-integration-test-example/