Spring Boot/testing
RestController 단위 Testing
최-코드
2024. 11. 13. 18:19
MockMvc
- 웹, REST API 등을 위한 요청과 응답을 처리할 수 있는 도구이다.
- 서버를 실제로 실행할 필요없다. MockMvc는 서버 컨테이너(tomcat, jetty, ...)를 Mock하여 테스트를 수행한다.
- DispatcherServlet과 비슷한 방식으로 요청을 처리한다.
@WebMvcTest(specifyController.class)
- @WebMvcTest는 컨트롤러와 관련된 웹 계층의 bean들만 로드한다. 이는 service, repository 등의 다른 계층 빈들을 로드하지 않기 때문에 테스트 속도가 빠르고, 웹 계층에 대한 집중적인 테스트가 가능하다.
- 추가적으로 테스트하고자 하는 특정 컨트롤러를 지정할 수 있다. 이를 통해 필요한 컨트롤러만 로드하여 테스트의 효율성을 높일 수 있다.
- 또한 @WebMvcTest를 사용할 경우 @Mock 대신 @MockitoBean을 사용해야 한다.
- service에 @Mock을 사용할 시에는 service에 필요한 의존성을 추가해줘야 한다. 이는 service가 @InjectMock으로 선언되어야 하는 것과 마찬가지이므로 컨트롤러 단위 테스트에 맞지 않는다.
- @WebMvcTest를 하면 컨텍스트를 로드하므로 @MockitoBean을 사용하면 컨텍스트에 빈으로 등록해준다. @MockitoBean으로 설정된 것에 대해 의존성은 자동으로 @Mock으로 설정된다.
- @WebMvcTest에서는 MockMvc가 자동으로 주입할 수 있게 해주지만, @SpringBootTest에서는 @AutoConfigureMockMvc 어노테이션을 통해 MockMvc가 주입될 수 있게 해준다. 이 때 security와 같은 필터를 포함하지 않으려면 addFilters의 값을 false로 하면 된다.
example
@Autowired
private MockMvc mvc;
...
public static final MediaType APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON;
@Test
public void createAValidGradeHttpRequest() throws Exception {
//MyGradeRequestDto myGradeRequestDto = new MyGradeRequestDto(~~);
//MyGradeResponseDto myGradeResponseDto = new MyGradeResponseDto(~~);
mockMvc.perform(post("/grades")
.principal(()-> UUID.randomUUID().toString())
.contentType(MediaType.APPLICATION_JSON))
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(myGradeRequestDto))
.andExpect(status().isOk()) // 1
.andExpect(content().contentType(APPLICATION_JSON_UTF8)) // 2
// 3~
//.andExpect(content().json(objectMapper.writeValueAsString(myGradeResponseDto)))
.andExpect(jsonPath("$.id", Mathers.is(1)))
.andExpect(jsonPath("$.firstname", is("Eric")))
.andExpect(jsonPath("$.lastname", is("Roby")))
.andExpect(jsonPath("$.emailAddress", is("eric.roby@luv2code_school.com")))
.andExpect(jsonPath("$.studentGrades.mathGradeResults", hasSize(2)));
}
...
- 상태코드를 검증하려면 위에 1번과 같이 해주면 된다.
- 응답 타입을 검증하려면 2번과 같이 해주면 된다.
- 3번 이후 검증 대상은 응답 바디이다.
- 주석처리 된 방식으로 진행하면 json 형태가 동일한 형태인지 검증할 수 있다.
- 주석이 안 된 방식은 jsonPath를 이용한 검증 방식이다. 이를 통해 특정 필드나 json 배열의 사이즈 값 등을 검증할 수 있다.
- jsonPath에 대한 문법은 https://0soo.tistory.com/190를 참고하자.
- is("인자")는 json에서 해당하는 값이 "인자"인지 검증해주고
- hasSize(num)은 json에서 해당 배열의 개수가 num개인지 검증해준다.