gpt4 book ai didi

unit-testing - 使用包含 Autowiring 属性的 ControllerAdvice 进行 WebMvc 测试

转载 作者:行者123 更新时间:2023-12-05 06:34:15 26 4
gpt4 key购买 nike

考虑到以下代码是最新版本的 SpringBoot 应用程序的一部分,在某些项目中,测试结果是无法启动应用程序,因为它未能将 ErrorMessages 注入(inject) ControllerAdvice。但出于某种原因,在其他项目中,这段代码通过了。我在配置、gradle-build 或注释方面没有任何差异,所以不完全确定我是否发现了错误。有什么方法可以影响在 @WebMvcTest 上读取和注入(inject) ErrorMessages 吗?

Controller 文件夹上的 Controller

@RestController
@Api(value = "Some Service", tags = "Some Service")
public class SomeController {

@Autowired
SomeService someService;

@ApiOperation(value = "Gets something")
@ApiResponses(value = {
@ApiResponse(code = 200, message = "OK"),
@ApiResponse(code = 500, message = "Internal server error", response = ErrorResponse.class) })
@GetMapping(value = "/something", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<SomeResponse> getSomething(
@AuthenticationPrincipal CustomOAuth2Authentication authentication,
) throws ApiException {
return ResponseEntity.ok(someService.get());
}
}

关于异常文件夹的 Controller 建议

@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class GlobalExceptionHandler {

@Autowired
private ErrorMessages errorMessages;

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Throwable.class)
@ResponseBody
public ErrorResponse handler(HttpServletRequest request, final Throwable ex)
{
log.error("Unexpected error", ex);
return new ErrorResponseBuilder().with(it -> {
it.status = ErrorCodes.INTERNAL_SERVER_EXCEPTION;
it.error = ex.getLocalizedMessage();
it.exception = ex.getClass().getName();
it.messages = Collections.singletonList(errorMessages.internalServerException);
it.path = request.getRequestURI();
}).build();
}
}

异常文件夹上的错误消息(从 Spring Cloud 读取)

@Component
public class ErrorMessages {

@Value("${"+ErrorCodes.INTERNAL_SERVER_EXCEPTION +"}")
public String internalServerException;

}

异常文件夹的错误代码

public class ErrorCodes {
private ErrorCodes() {}

public static final String INTERNAL_SERVER_EXCEPTION = "3031";
}

测试文件夹中的测试类

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = SomeController.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {ErrorMessages.class,
GlobalExceptionHandler.class})
public class SomeControllerTest {

private String SERVICE_URL = "/some";

@Autowired
private MockMvc mockMvc;

@Autowired
private WebApplicationContext wac;

@Before
public void setup() throws ApiException {

this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.wac)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();
}

@Autowired
ErrorMessages errorMessages;

@MockBean
private SomeService someService;

@Autowired
@InjectMocks
private SomeController someController;

@Test
@WithMockCustomUser()
public void getCheckout_Exception() throws Exception {
ApiException e = new ApiException("code123", "message123");
when(someService.get(anyString(), anyInt())).thenThrow(e);
mockMvc.perform(get(SERVICE_URL))
.andExpect( status().is( equalTo(
HttpStatus.INTERNAL_SERVER_ERROR.value())))
.andExpect( content().string(containsString(e.getClass().getName())))
.andExpect( content().string(containsString(e.getCode())))
.andExpect( content().string(containsString(e.getMessage())))
.andExpect( content().string(containsString(errorMessages.transformingException)));
}
}

错误是

java.lang.IllegalStateException: Failed to load ApplicationContext

at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79)
at org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.java:54)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'globalExceptionHandler': Unsatisfied dependency expressed through field 'errorMessages'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.comp.proj.service.something.exception.ErrorMessages' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:587)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:373)

最佳答案

您可以尝试在您的测试类中导入您的异常处理程序:

@RestController
@Api(value = "Some Service", tags = "Some Service")
@Import(GlobalExceptionHandler.class) // EXCEPTION HANDLER CLASS
public class SomeController {

关于unit-testing - 使用包含 Autowiring 属性的 ControllerAdvice 进行 WebMvc 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50346505/

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