2017-10-03 7 views
0

@Valid 주석을 사용하여 컨트롤러 끝점과 요청자를 테스트하려고합니다. 내 TestClass에는 다음과 같습니다SpringWebMvcTest - @Valid 및 사용자 정의 유효성 검사를 사용하여 요청 바디 테스트

@RunWith(SpringRunner.class) 
@WebMvcTest(value = BalanceInquiryController.class, secure = false) 
public class BalanceInquiryControllerTest { 

    @Autowired 
    private MockMvc mockMvc; 

    @MockBean 
    private BalanceInquiryController balanceInquiryController; 

    @Test 
    public void testGetBalanceInquiry() throws Exception { 
     RequestBuilder requestBuilder = MockMvcRequestBuilders 
       .post("/com/balanceInquiry") 
       .accept(MediaType.APPLICATION_JSON) 
       .content("{\"comGiftCard\":{\"cardNumber\":\"1234567890\",\"pinNumber\":\"0123\"},\"comMerchant\":\"MERCHANT1\"}") 
       .contentType(MediaType.APPLICATION_JSON); 

     MvcResult mvcResult = mockMvc.perform(requestBuilder).andReturn(); 
     MockHttpServletResponse response = mvcResult.getResponse(); 
     assertEquals(HttpStatus.OK.value(), response.getStatus()); 
    } 
} 

내 컨트롤러 - @PostMapping 그 다음과 같습니다

@PostMapping(value = "/com/balanceInquiry") 
public ResponseEntity<?> getBalanceInquiry(@Valid @RequestBody BalanceInquiryModel balanceInquiry, Errors errors) { 
    if (errors.hasErrors()) { 
     return new ResponseEntity<String>("Validation error", HttpStatus.BAD_REQUEST); 
    } 
    //do any stuff... 
    return new ResponseEntity<BalanceInquiryResponse>(balanceInquiryResponse, HttpStatus.OK); 
} 

BalanceInquiryModel@Valid 주석 뒤에 일부 최대 절전 모드 및 사용자 정의 검증을 가지고 있습니다. 이러한 유효성 검사는 모두 정상이며 이미 단위 테스트를 거쳤습니다.

필자가 테스트하고자하는 엔드 포인트는 올바른 응답을 기대하는 json 요청 본문과 20034 응답을 기대하는 잘못된 json 요청 본문 (@Valid 집합으로 유효성이 검증 됨)을 보내는 엔드 포인트입니다.

는 예를 들어 unvalid 호출 내가 전체 컨트롤러를 조롱하는 일부 스레드와 일부 사용 MockMvcBuilders.standaloneSetup()을 읽고 < 4.

더 pinNumber 또는 길이를 보낼 것입니다. 하지만 나는 완전한 통합 테스트를하지 않을 것이다.

이 상황을 어떻게 진행하고 계속해야하는지에 대해서는 잘 모릅니다.

추신 : 현재 유효성 검사에서 오류가 발생하는지 여부와 관계없이 항상 200 응답을 얻습니다.

Here a gist 더 많은 코드와 유효성 검사 클래스/모델.

+0

당신이 우편 배달부에서 테스트 않았고이 때 검증 당신에게 400를 얻을 것이다 :

하지만 귀하의 경우

, 당신은 그것을 봄 유효성 검사를 실행하려면, 당신은 세부에 대한 @SpringBootTest

를 사용해야합니다 실패한? –

+0

@ChiDov 예. 예를 들어, 내가 pinNumber 길이 <4를 보낼 때 – Patrick

답변

1

여기에 당신을 도울 희망 내 프로젝트에 대한 작업을 내 예 중 하나입니다 :

내가 내 MethodArgumentNotValidException을 핸들러 던져 글로벌 예외 핸들러가 그것을

@RequestMapping(value = "/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE) 
    public ResponseEntity<User> createUser(@Valid @RequestBody User user) { 

     User savedUser = userService.save(user); 

     return new ResponseEntity<User>(savedUser, HttpStatus.CREATED); 
    } 


public void testAdduser() throws Exception{ 
     final User request = new User(); 
     request.setFirstName("Test"); 
     request.setLastName("some description"); 

     mockMvc.perform(post(END_POINT+"/add") 
       .contentType(MediaType.APPLICATION_JSON) 
       .content(stringify(request)) 

     ).andDo(print()).andExpect(status().isUnprocessableEntity()) 
     ; 
    } 
private String stringify(Object object) throws JsonProcessingException { 
     return new ObjectMapper().writeValueAsString(object); 
    } 

업데이트 :

당신의 주된 문제는 @WebMvcTest 대신 대신 @SpringBootTest을 사용하고 있다는 것입니다.

@SpringBootTest 주석 것이다 부하 완벽한 애플리케이션이며 느린 될 수있는 모든 콩을 주입 :

그 중 2 사이의 서로 다른 그 것이다.

@WebMvcTest - 컨트롤러 레이어 테스트 용. @RestController 옆에 다른 콩을 주입하지 않습니다

그래서 순수한 컨트롤러 만 테스트하면 u가 엔드 포인트에 도달하는지 확인할 수 있습니다. 그런 다음 @WebMvcTest를 사용하면 테스트를 빠르게 실행할 수 있습니다. https://spring.io/guides/gs/testing-web/

+0

당신이 firstname을 보내지 않는다면, 당신의 검증은 괜찮은가요? – Patrick

+0

그것은 실제로 사용자 개체가 다른 유효성 검사를 가졌으므로 y는 성가신 성을 보내더라도 y는 200을 반환하지 않을 것입니다. –

+0

이것은 나를 위해 작동하지 않습니다. 아직도 200의 응답을 얻으 십시요 – Patrick