[SPRING] Spring MockMVC - 컨트롤러 외부에서 실행되는 커스텀 유효성 검사기를 조롱하는 법
SPRINGSpring MockMVC - 컨트롤러 외부에서 실행되는 커스텀 유효성 검사기를 조롱하는 법
@UsernameAlreadyExists
private String username;
계정 작성 양식을 제출할 때 중복 된 사용자 이름이 응용 프로그램에 의해 잡히도록하기 위해 만든 사용자 정의 유효성 검사기가 있습니다.
MockMVC를 사용하여 계정 생성 컨트롤러를 테스트 할 때 유효성 검사기가 서비스에 의존하기 때문에 실패합니다. 따라서 널 포인터 예외가 발생합니다.
이 유효성 검사기가 의존하는 유효성 검사기 또는 서비스를 조롱하려면 어떻게해야합니까? 컨트롤러가 명시 적으로 유효성 검사기에 의존하지 않고 컨트롤러 외부에서 실행되므로이 작업을 수행하는 방법을 알 수 없습니다.
해결법
-
==============================
1.ConstraintValidator를 조롱 할 수는 없지만, 예를 들어 콩을 조롱하는 일반적인 스프링 방법을 사용하여 유효성 검사기가 의존하는 서비스를 조롱 할 수 있습니다.
ConstraintValidator를 조롱 할 수는 없지만, 예를 들어 콩을 조롱하는 일반적인 스프링 방법을 사용하여 유효성 검사기가 의존하는 서비스를 조롱 할 수 있습니다.
.1. 잠재적으로 동일한 bean 이름을 가진 mock 인스턴스를 정의하여 모의 인스턴스가 실제 인스턴스 다음에로드되도록합니다.
.2. mock bean 만 정의 된 테스트 구성으로 테스트하십시오.
-
==============================
2.전체 Spring 컨텍스트를로드하지 않고 'standaloneSetup'을 사용하여 테스트 할 때 유효성 검사는 SpringWebConstraintValidatorFactory의 프레임 워크 호출에 의해 내부적으로 트리거됩니다. 해당 흐름에 연결하려면 'mockMvc'에 SpringWebConstraintValidatorFactory의 새 인스턴스를 설정해야합니다. 불행히도 그렇게 쉬운 방법은 쉽지 않습니다. SpringWebConstraintValidatorFactory를 서브 클래스 화하고 mockMvc에서 차례대로 설정할 수있는 LocalValidatorFactoryBean에 인스턴스를 설정해야한다. 그러나 LocalValidatorFactoryBean은 ApplicationContext를 필요로합니다. 다음은 그 예입니다.
전체 Spring 컨텍스트를로드하지 않고 'standaloneSetup'을 사용하여 테스트 할 때 유효성 검사는 SpringWebConstraintValidatorFactory의 프레임 워크 호출에 의해 내부적으로 트리거됩니다. 해당 흐름에 연결하려면 'mockMvc'에 SpringWebConstraintValidatorFactory의 새 인스턴스를 설정해야합니다. 불행히도 그렇게 쉬운 방법은 쉽지 않습니다. SpringWebConstraintValidatorFactory를 서브 클래스 화하고 mockMvc에서 차례대로 설정할 수있는 LocalValidatorFactoryBean에 인스턴스를 설정해야한다. 그러나 LocalValidatorFactoryBean은 ApplicationContext를 필요로합니다. 다음은 그 예입니다.
public class TestConstrainValidationFactory extends SpringWebConstraintValidatorFactory { private final WebApplicationContext ctx; private boolean isValid = false; public TestConstrainValidationFactory(WebApplicationContext ctx) { this.ctx = ctx; } @Override public < T extends ConstraintValidator<?, ?>> T getInstance(Class key) { ConstraintValidator instance = super.getInstance(key); if (instance instanceof DeviceValidator) { DeviceValidator deviceValidator = (DeviceValidator) instance; deviceValidator.setYourAutowiredField((String id, String type) -> isValid); //change that to suit your needs instance = deviceValidator; } return (T) instance; } @Override protected WebApplicationContext getWebApplicationContext() { return ctx; } }
그것을 mockMvc에 연결하는 예제
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = MockServletContext.class) @WebAppConfiguration() public class DevicesControllerTest { @Autowired private MockServletContext servletContext; @InjectMocks private DevicesController devicesController; private TestConstrainValidationFactory constraintFactory; @Before public void setUp() { MockitoAnnotations.initMocks(this); final GenericWebApplicationContext context = new GenericWebApplicationContext(servletContext); final ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) context).getBeanFactory(); beanFactory.registerSingleton(DeviceValidator.class.getCanonicalName(), new DeviceValidator()); context.refresh(); LocalValidatorFactoryBean validatorFactoryBean = new LocalValidatorFactoryBean(); validatorFactoryBean.setApplicationContext(context); constraintFactory = new TestConstrainValidationFactory(context); validatorFactoryBean.setConstraintValidatorFactory(constraintFactory); validatorFactoryBean.setProviderClass(HibernateValidator.class); validatorFactoryBean.afterPropertiesSet(); this.mockMvc = MockMvcBuilders .standaloneSetup(devicesController) .setValidator(validatorFactoryBean) .setHandlerExceptionResolvers() .build(); } }
일단 당신이 그것을 가지고, ReflectionTestUtils.setField (constraintFactory, "isValid", 거짓); 예상대로 작동하고 공장을 통해 검사기에서 필드를 설정할 수 있습니다. 문제 상황보기 spring-projects / spring-test-mvc / issues :
from https://stackoverflow.com/questions/23161752/spring-mockmvc-how-to-mock-custom-validators-running-outside-of-controllers by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄 배치 및 봄 통합 (0) | 2019.04.29 |
---|---|
[SPRING] Spring MVC에서 하나의 폼에 대한 많은 commandName (0) | 2019.04.29 |
[SPRING] 카프카 탄력성 - 그룹 코디네이터 (0) | 2019.04.28 |
[SPRING] 왜 봄 ReactiveMongoRepository는 모노에 대한 저장 방법을 가지고 있지 않습니까? (0) | 2019.04.28 |
[SPRING] 값에 대해 Redis에서 데이터를 모델링하는 방법 복잡한 데이터 구조? (0) | 2019.04.28 |