Step 1, have a general exception
@GetMapping("/exception/throw")
public void getException() throws Exception {
throw new Exception("error");
}
Then, you test with Postman, you will see the following error message.
{
"timestamp": "2021-07-31T23:23:21.163+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/exception/throw"
}
Step 2, define customized exceptions
BadArgumentsException.java
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadArgumentsException extends RuntimeException {
public BadArgumentsException(String message) {
super(message);
}
}
ResourceNotFoundException.java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
InternalException.java
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public class InternalException extends RuntimeException {
public InternalException(String message) {
super(message);
}
}
Then, define this REST api to trigger different exceptions
// For not_found, we receive a response code of 404
// Given the value bad_arguments, we receive a response code of 400
// For any other value, we still receive 500 as the response code
@GetMapping("/exception/{exception_id}")
public void getSpecificException(@PathVariable("exception_id") String pException) {
if("not_found".equals(pException)) {
throw new ResourceNotFoundException("resource not found");
}
else if("bad_arguments".equals(pException)) {
throw new BadArgumentsException("bad arguments");
}
else {
throw new InternalException("internal error");
}
}
Finally, we are going to test these exceptions
DemoApplicationTest.java
@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {
@Autowired
UserRepository userRepository;
@Autowired
private MockMvc mvc;
@Test
void testSaveWithSameAge() {
userRepository.save(new User("shark", 29L));
userRepository.save(new User("mary", 29L));
}
@Test
void testDummy() {
assertEquals(1, 1);
}
@Test
public void testNotFound() throws Exception {
mvc.perform(get("/exception/{exception_id}", "not_found")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
.andExpect(result -> assertTrue(result.getResolvedException() instanceof ResourceNotFoundException))
.andExpect(result -> assertEquals("resource not found", result.getResolvedException().getMessage()));
}
@Test
public void testBadArguments() throws Exception {
mvc.perform(get("/exception/{exception_id}", "bad_arguments")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(result -> assertTrue(result.getResolvedException() instanceof BadArgumentsException))
.andExpect(result -> assertEquals("bad arguments", result.getResolvedException().getMessage()));
}
@Test
public void testInternalServer() throws Exception {
mvc.perform(get("/exception/{exception_id}", "dummy")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isInternalServerError())
.andExpect(result -> assertTrue(result.getResolvedException() instanceof InternalException))
.andExpect(result -> assertEquals("internal error", result.getResolvedException().getMessage()));
}
}