gpt4 book ai didi

java - 使用自定义异常处理测试 REST 端点

转载 作者:行者123 更新时间:2023-11-28 20:52:26 26 4
gpt4 key购买 nike

我正在使用 Spring 微服务(模块)开发一个项目,我想使用 MockMvc 测试我的 REST 端点。我的测试在请求有效但在请求无效 url 时不起作用的情况下工作正常。不工作是指我的自定义异常处理程序 (@ControllerAdvice) 没有被调用,异常被抛出并且测试失败。

我的异常处理程序和测试类在不同的模块中实现。

通用模块(ExceptionHandler)

@ControllerAdvice
public class CoreExceptionHandler {

@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorMessageDTO> handleException(Exception ex, HttpServletRequest request) {

// Getting servlet request URL
String uri = request.getRequestURI();
HttpStatus a;

ErrorMessageDTO errorMessage;

if (ex instanceof CoreException) {
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else {
errorMessage = new ErrorMessageDTO(ex, uri);
...
}
return new ResponseEntity<ErrorMessageDTO>(errorMessage, a);
}
}

国家模块

这是实现我的 REST 端点和测试类的地方。公共(public)模块依赖包含在该模块的pom.xml中,并通过主类扫描包。

CountryApplication.java

@EnableCaching
@EnableDiscoveryClient
@EnableAspectJAutoProxy
@SpringBootApplication(scanBasePackages = {
"com.something1.something2.something3.common.exception",
"com.something1.something2.something3.common.util.logged",
"com.something1.something2.something3.country"
})
public class CountryApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(CountryApplication.class, args);
}
...
}

国家服务.java

这是我的服务类中的一个方法。

@GetMapping("/{id:\\d+}")
public CountryDTO getCountryById(@PathVariable("id") Integer id) throws CoreException {

Country countryEntity = this.countryRepository.findOne(id);

// requesting for id that does not exist
if (countryEntity == null) {
throw new CoreException(CoreError.ENTITY_NOT_FOUND);
}
return this.countryMapper.daoToDto(countryEntity);
}

CountryServiceTest.java

@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
public class CountryServiceTest {
...
@Autowired
private MockMvc mockMvc;

@Test
public void getByIdTest() throws Exception {

// Get by id exists
mockMvc.perform(get("/2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andDo(print());

// Get by id not exists. NOT WORKING
mockMvc.perform(get("/100000"))
.andExpect(status().isNotFound())
.andExpect(content().contentType(contentType));

}
}

正如我上面所描述的,问题是在测试方法的第二个请求中,CoreExceptionHandler 没有被调用并且测试失败抛出:

NestedServletException:请求处理失败;嵌套异常是 com.something1.something2.something3.common.exception.CoreException

公共(public)模块的依赖性配置良好(至少当我在非测试模式下部署时),因为我也将它用于其他事情,而且当我不测试时会调用 ExceptionHandler。

另一件奇怪的事情是,当我部署我的测试时,Spring Boot 的日志显示检测到 CoreExceptionHandler。这是线。 在 coreExceptionHandler 中检测到 @ExceptionHandler 方法

最佳答案

有两个问题解释如下:

(1) ControllerAdvice 没有为 CountryServiceTest 类中的 MockMvc 对象设置,可以如下所示完成:

MockMvc mockMvc = standaloneSetup(yourController)
.setHandlerExceptionResolvers(new CoreExceptionHandler())
.build();

(2) 因为 CoreException 是 Spring 容器对 NestedServletException 的包装,所以需要使用 exception.getCause() 来检查您的异常,如下所示:

@ControllerAdvice
public class CoreExceptionHandler {

@ExceptionHandler(value = Exception.class)
public ResponseEntity<ErrorMessageDTO> handleException(Exception ex,
HttpServletRequest request) {

// Getting servlet request URL
String uri = request.getRequestURI();
HttpStatus a;

ErrorMessageDTO errorMessage;

//check with exception cause
if (ex.getCause() instanceof CoreException) {
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else if (ex instanceof CoreException) {
//this block will be used only when direct CoreException triggered
CoreException e = (CoreException) ex;
...
errorMessage = new ErrorMessageDTO(e, uri);
} else {
errorMessage = new ErrorMessageDTO(ex, uri);
...
}
return new ResponseEntity<ErrorMessageDTO>(errorMessage, a);
}
}

此外,我建议不要在一个泛型方法中处理所有异常类型,这将很难支持/维护,而是使用多个 @ExceptionHandler 拆分您的 CoreExceptionHandler 方法/类。

关于java - 使用自定义异常处理测试 REST 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40626785/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com