스프링 MVC 컨트롤러 유닛테스트가 @ControllerAdvice를 호출하지 않음
이는 「컨트롤러」라고 코멘트가 붙어 있습니다.@ControllerAdvice각 컨트롤러에서 사용되는 특정 데이터 요소를 설정합니다.하고 Spring MVC 3.2Junits를 이 컨트롤러에 사용합니다.하면 컨트롤이 Junit으로 .ControllerAdviceTomcat이치노
아무 생각 없어요?
@to의 답변과 다른 유사한 답변을 사용한 후 제한을 발견하여 https://jira.spring.io/browse/SPR-12751에서 문제를 제기하였습니다.
을 등록할 수 기능이 도입되었습니다.@ControllerAdvice4.2의 빌더에 있는 클래스입니다.스프링 부트를 사용하고 있는 경우는, 1.3.0 이후가 필요합니다.
하는 경우 을 할 수 .ControllerAdvice다음과 같이 합니다.
mockMvc = MockMvcBuilders.standaloneSetup(yourController)
.setControllerAdvice(new YourControllerAdvice())
.build();
주의: 이름setControllerAdvice()에는 var-instature 시그니처가 포함되어 있기 때문에 즉시 명확하게 할 수는 없지만 많은 인스턴스를 전달할 수 있습니다.
클래스 MyControllerAdvice에 @ControllerAdvice에 주석이 달렸고 @ExceptionHandler에 주석이 달린 메서드가 있다고 가정합니다.MockMvc의 경우 이 클래스를 예외 해결사로 쉽게 추가할 수 있습니다.
@Before
public void beforeTest() {
MockMvc mockMvc = standaloneSetup(myControllers)
.setHandlerExceptionResolvers(createExceptionResolver())
.build();
}
private ExceptionHandlerExceptionResolver createExceptionResolver() {
ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
Method method = new ExceptionHandlerMethodResolver(MyControllerAdvice.class).resolveMethod(exception);
return new ServletInvocableHandlerMethod(new MyControllerAdvice(), method);
}
};
exceptionResolver.afterPropertiesSet();
return exceptionResolver;
}
할 때도 요.ExceptionHandler'어느 정도'라는 주석이 붙어 .@ControllerAdvice에는 '아예'를 @Configuration@EnableWebMvc을 붙일 수 있습니다.@ContextConfiguration시험 수업 중에
그래서 제 테스트는 이렇습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {
RestProcessingExceptionHandler.class,
TestConfiguration.class,
RestProcessingExceptionThrowingController.class })
public class TestRestProcessingExceptionHandler {
private MockMvc mockMvc;
@Autowired
WebApplicationContext wac;
@Before
public void setup() {
mockMvc = webAppContextSetup(wac).build();
}
@Configuration
// !!! this is very important - conf with this annotation
// must be included in @ContextConfiguration
@EnableWebMvc
public static class TestConfiguration { }
@Controller
@RequestMapping("/tests")
public static class RestProcessingExceptionThrowingController {
@RequestMapping(value = "/exception", method = GET)
public @ResponseBody String find() {
throw new RestProcessingException("global_error_test");
}
}
@Test
public void testHandleException() throws Exception {
mockMvc.perform(get("/tests/exception"))
.andExpect(new ResultMatcher() {
@Override
public void match(MvcResult result) throws Exception {
result.getResponse().getContentAsString().contains("global_error_test");
}
})
.andExpect(status().isBadRequest());
}
}
★★★★★★★★★★★★★★★★ @EnableWebMvc이치노
이 코드는 유효합니다.
public class MyGlobalExceptionHandlerTest {
private MockMvc mockMvc;
@Mock
HealthController healthController;
@BeforeTest
public void setUp() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(healthController)
.setControllerAdvice(new GlobalExceptionHandler())
.build();
}
@Test(groups = { "services" })
public void testGlobalExceptionHandlerError() throws Exception {
Mockito.when(healthController.health())]
.thenThrow(new RuntimeException("Unexpected Exception"));
mockMvc.perform(get("/health")).andExpect(status().is(500));
}
}
나는 꽤 오랫동안 같은 일로 고생해 왔다.자세히 살펴본 결과, 가장 좋은 참고 자료는 Spring 문서였습니다.
즉, 컨트롤러와 그 메서드를 단순히 테스트하는 경우에는 간단한 Spring MVC 설정을 작성하는 'standalone Setup' 방식을 사용할 수 있습니다.여기에는 @ControllerAdvice로 주석을 다는 오류 핸들러는 포함되지 않습니다.
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}
// ...
에러 핸들러를 포함한 보다 완전한 Spring MVC 설정을 작성하려면 , 다음의 설정을 사용할 필요가 있습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class AccountTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Autowired
private AccountService accountService;
// ...
}
ControllerAdvice 한다@WebMvcTestSpring-Doc Works도 참조해 주세요.
예:
@RunWith(SpringRunner.class)
@WebMvcTest(ProductViewController.class)
@sampleuski 샘플 코드는 동작하지만, 동작의 구조를 이해하는 것은 유익합니다.이것은 설정 방법 중 하나일 뿐입니다.
@EnableWebMvc.
<mvc:annotation-driven />
기본적으로는 Spring MVC를 초기화하고 모든 컨트롤러와 빈 레퍼런스를 로드해야 합니다.따라서 다음 설정은 유효한 설정일 뿐만 아니라 대체 설정일 수도 있습니다.
테스트 클래스를 설정하는 방법은 다음과 같습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath: "classpath:test-context.xml" })
@WebAppConfiguration
public class BaseTest {
@Autowired
WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setUp() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
테스트용 스프링 구성은 다음과 같습니다.
<mvc:annotation-driven />
<context:component-scan base-package="com.base.package.controllers" />
이 문제는 spark(groovy)로 컨트롤러 테스트를 작성하는 중에 발생했습니다.저의 시험 수업은 원래 다음과 같이 작성되었습니다.
@AutoConfigureMockMvc(secure = false)
@SpringBootTest
@Category(RestTest)
class FooControllerTest extends Specification {
def fooService = Mock(FooService)
def underTest = new FooController(FooService)
def mockMvc = MockMvcBuilders.standaloneSetup(underTest).build()
....
}
이로 인해 ControllerAdvice는 무시되었습니다.코드를 [Autowire](자동 배선)으로 변경하면 문제가 해결.
@AutoConfigureMockMvc(secure = false)
@SpringBootTest
@Category(RestTest)
class FooControllerTest extends Specification {
@AutowiredMock
FooService FooService
@Autowired
MockMvc mockMvc
구체적인 답변을 예상하기 전에 추가 정보 및 실제 코드 및/또는 구성 파일을 제공해야 합니다.단, 당신이 제공한 소량으로 볼 때 주석이 달린 콩이 로딩되지 않은 것 같습니다.
다음 항목을 테스트 applicationContext.xml(또는 동등한 스프링 설정 파일(사용하는 경우))에 추가해 보십시오.
<context:component-scan base-package="com.example.path.to.package" />
또는 테스트 클래스 전에 다음 주석을 포함하여 테스트 내에 콘텍스트를 '수동으로' 로드해야 할 수도 있습니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
행운을 빕니다.
테스트에서 asyncDispatch를 사용해야 할 것 같습니다.일반 테스트 프레임워크는 비동기 컨트롤러로 망가져 있습니다.
다음 URL에서 접근 방법을 사용해 보십시오.https://github.com/spring-projects/spring-framework/blob/master/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/AsyncTests.java
가장 간단한 방법은 @ControllerAdvice 주석 클래스를 @ContextConfiguration에 추가하는 것입니다.
나는 이것으로부터 변해야 했다.
@AutoConfigureMockMvc
@ContextConfiguration(classes = OrderController.class)
@WebMvcTest
class OrdersIntegrationTest
다음과 같이 입력합니다.
@AutoConfigureMockMvc
@ContextConfiguration(classes = {OrderController.class, OrdersExceptionHandler.class})
@WebMvcTest
class OrdersIntegrationTest
Spring Boot 2.x를 사용하고 있습니다만, MockMvcBuilders가 필요 없게 되었거나 ControllerAdvice를 Configuration의 일부로 정의하고 있기 때문에 로드됩니다.
@WebMvcTest
@ContextConfiguration(classes = {
UserEndpoint.class, //the controller class for test
WebConfiguration.class, //security configurations, if any
StandardRestExceptionInterpreter.class. //<-- this is the ControllerAdvice class
})
@WithMockUser(username = "test@asdf.com", authorities = {"DEFAULT"})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UserEndpointTests {
@Test
@Order(3)
public void shouldThrowExceptionWhenRegisteringDuplicateUser() throws Exception {
//do setup...
Mockito.doThrow(EntityExistsException.class).when(this.userService).register(user);
this.mockMvc
.perform(MockMvcRequestBuilders
.post("/users")
.contentType(MediaType.APPLICATION_JSON)
.content(this.objectMapper.writeValueAsString(user)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isConflict());
}
}
@WebMvcTest를 특정 컨트롤러와 함께 사용하는 경우 컨트롤러 어드바이저는 스프링 구성(https://github.com/spring-projects/spring-boot/issues/12979에서 사용되지 않습니다.
@Import 주석을 통해 스프링에 컨트롤러 조언을 사용하도록 명시적으로 지시할 수 있습니다.
@WebMvcTest(controllers = AppController.class)
@Import(AppControllerAdvice.class)
class AppControllerTest {
@Autowired
private MockMvc mockMvc;
}
같은 문제가 있었는데 @Spring Boot 클래스에 어드바이저를 추가하여 해결했습니다.테스트:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyController.class, MyControllerAdvice.class})
@AutoConfigureMockMvc(secure = false)
@ContextConfiguration(classes = {MyTestConfig.class})
@EnableWebMvc
언급URL : https://stackoverflow.com/questions/15302243/spring-mvc-controllers-unit-test-not-calling-controlleradvice
'programing' 카테고리의 다른 글
| JDBC Prepared Statement에서 LIKE 쿼리를 사용할 수 없습니까? (0) | 2023.03.18 |
|---|---|
| 조인트WP4(SASS): 스틱 속성 변경 (0) | 2023.03.18 |
| angular ng-if 또는 ng-show 응답이 느립니다(2초 지연) (0) | 2023.03.18 |
| Oracle에서의 Base64 인코딩 및 디코딩 (0) | 2023.03.18 |
| ASP를 통해 JSON 날짜 값을 전달하는 방법.JSON을 사용한NET MVC인터넷? (0) | 2023.03.18 |