英文:
How to test custom ExceptionHandlers for annotations referenced by @ControllerAdvice?
问题
我正在基于Spring Cloud开放式服务代理框架开发服务代理。我正在使用一个继承自ServiceBrokerExceptionHandler的自定义ExceptionHandler来调整所有ServiceBrokerRestControllers上特定情况的HTTP状态码:
@ControllerAdvice(annotations = ServiceBrokerRestController.class)
public class MyServiceBrokerExceptionHandler extends ServiceBrokerExceptionHandler {
    @ExceptionHandler({MyCustomException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorMessage handleException(MyCustomException ex) {
        return this.getErrorResponse(ex);
    }
}
现在我想要对其进行测试,但我真的不太明白如何做。由于该处理程序适用于所有使用@ServiceBrokerRestController注释的控制器,我实际上并不关心特定的控制器bean,更不用说特定的方法了。我只想“模拟”某种类型的ServiceBrokerRestController,并且在其方法之一抛出MyCustomException时,Web层应返回500 - 内部服务器错误。我是否需要为此创建一个虚拟的ServiceBrokerRestController,或者有更好的方法?
英文:
I am working on a service broker based on the Spring Cloud Open Service Broker framework. I'm using a custom ExceptionHandler which inherits from ServiceBrokerExceptionHandler to adjust the HTTP status code for certain situations on all the ServiceBrokerRestControllers:
@ControllerAdvice(annotations = ServiceBrokerRestController.class)
public class MyServiceBrokerExceptionHandler extends ServiceBrokerExceptionHandler {
    @ExceptionHandler({MyCustomException.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorMessage handleException(MyCustomException ex) {
        return this.getErrorResponse(ex);
    }
}
Now I want to test it but I don't really understand how. Since the handler is applied to all controllers annotated with @ServiceBrokerRestController I don't really care about a certain controller bean let aside a certain method. I just want to "mock" some kind of ServiceBrokerRestController and given one of its methods throws a MyCustomException the web layer should return with 500 - Internal Server Error. Do I have to create a ServiceBrokerRestController dummy for that or is there a better way?
答案1
得分: 1
以下是翻译好的部分:
虚拟控制器:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DummyExceptionTestController {
    @GetMapping("/my-exception")
    public void customException() {
        throw new MyCustomException("My Error Message 1");
    }
}
集成测试:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@AutoConfigureMockMvc
@SpringBootTest(classes = DemoApplication.class)
public class ExceptionHandlerIT {
    @Autowired
    private MockMvc mockMvc;
    @Test
    public void testMyException() throws Exception {
        mockMvc.perform(get("/my-exception"))
                .andExpect(status().isBadRequest())
                .andExpect(content().string("My Error Message 1"));
    }
}
异常处理程序和异常:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class MyServiceBrokerExceptionHandler {
    @ExceptionHandler({MyCustomException.class})
    public ResponseEntity<String> handleException(MyCustomException ex) {
        return ResponseEntity.badRequest().body(ex.getMessage());
    }
}
public class MyCustomException extends RuntimeException {
    public MyCustomException(String msg) {
        super(msg);
    }
}
英文:
It should be an simple integration as follows. You can create a dummy controller in your test package that just throws the exceptions that you want to test.
Dummy Controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DummyExceptionTestController {
    @GetMapping("/my-exception")
    public void customException() {
        throw new MyCustomException("My Error Message 1");
    }
}
The Integration test:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@AutoConfigureMockMvc
@SpringBootTest(classes = DemoApplication.class)
public class ExceptionHandlerIT {
    @Autowired
    private MockMvc mockMvc;
    @Test
    public void testMyException() throws Exception {
        mockMvc.perform(get("/my-exception"))
                .andExpect(status().isBadRequest())
                .andExpect(content().string("My Error Message 1"));
    }
}
Exception handler and the Exception:
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class MyServiceBrokerExceptionHandler {
    @ExceptionHandler({MyCustomException.class})
    public ResponseEntity<String> handleException(MyCustomException ex) {
        return ResponseEntity.badRequest().body(ex.getMessage());
    }
}
public class MyCustomException extends RuntimeException {
    public MyCustomException(String msg) {
        super(msg);
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论