GlobalExceptionHandlerTest.java
3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.xly.erp.common.exception;
import com.xly.erp.common.response.ErrorCode;
import jakarta.validation.constraints.NotBlank;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
class GlobalExceptionHandlerTest {
private MockMvc mockMvc;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new DummyController())
.setControllerAdvice(new GlobalExceptionHandler())
.build();
}
@RestController
@RequestMapping("/api/__dummy")
static class DummyController {
@GetMapping("/biz")
public Object biz() { throw new BizException(ErrorCode.MOD_PARENT_NOT_FOUND); }
@GetMapping("/runtime")
public Object runtime() { throw new RuntimeException("internal boom\nstack-line-1\nstack-line-2"); }
@PostMapping(value = "/validation", consumes = MediaType.APPLICATION_JSON_VALUE)
public Object validation(@jakarta.validation.Valid @RequestBody Payload p) { return "ok"; }
}
static class Payload {
@NotBlank String name;
public String getName() { return name; }
public void setName(String n) { this.name = n; }
}
@Test
void bizException_returns200WithBizCode() throws Exception {
mockMvc.perform(get("/api/__dummy/biz"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(40411))
.andExpect(jsonPath("$.message").value("父模块不存在或已删除"));
}
@Test
void validationException_returns200WithParamInvalidCode() throws Exception {
mockMvc.perform(post("/api/__dummy/validation")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\":\"\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(40010));
}
@Test
void uncaughtException_returns200WithInternalErrorCode() throws Exception {
mockMvc.perform(get("/api/__dummy/runtime"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(50000));
}
@Test
void response_doesNotContainStackTrace() throws Exception {
String body = mockMvc.perform(get("/api/__dummy/runtime"))
.andReturn().getResponse().getContentAsString();
assertThat(body)
.doesNotContain("stack-line-1")
.doesNotContain("internal boom")
.doesNotContain("at java.")
.doesNotContain("Caused by");
}
}