테스트 코드를 작성하는데 유용한 패턴이나 라이브러리를 작성하자. 주기적으로 업데이트할 예정~
Mock은 한글로 "모의, 가짜의"라는 뜻으로 테스트할 때 필요한 실제 객체와 동일한 모의 객체를 만들어 테스트의 효용성을 높이기 위해 사용한다. Mockito는 mock을 쉽게 만들고 mock의 행동을 정하는 stubbing, 정상적으로 작동하는지에 대한 verify 등 다양한 기능을 제공해주는 프레임워크입니다.
controller를 테스트하는데에는 MockMvc class를 이용해서 테스트를 할 수 있다.
@Autowired
MockMvc mockMvc;
@Test
@Description("적절하지 않은 요청을 보낸 Dto로 해결한 상홥입니다.")
void createEvent() throws Exception {
Event event = Event.builder()
.build(); // 생성자처럼 객체를 생성하는 과정
Mockito.when(eventRepository.save(event)).thenReturn(event); // Controller에서 eventRepsitory.save()를 호출할 때 인자가 현재 스코프의 event와 같다면
// Controller에서 save()로 반환받는 값을 현재 스코프의 event로 변경한다는 뜻
// client가 contentType을 json으로 오쳥하고 응답을 받는다.
ResultActions perform = mockMvc.perform(post("/api/events")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(event))); // event를 json형태로 변환해서 서버에게 넘긴다. 그러므로 서버에서도 json을 파싱해서 EventDto에게 넘겨줄 수 있는 것이다.
// 만약에 EventDto의 필드명이 Event의 필드명과 다르다면 받을 수 없다.
// 받은 응답으로 상태 코드를 학인한다.
perform.andExpect(status().isCreated())
.andDo(print());
}
이렇게 MockMvc 객체를 주입받아 이용해서 controller에게 POST, GET 등 다양한 http 요청을 보낼 수 있다.
테스트를 하다보면 같은 테스트를 데이터만 바꿔서 진행하는 경우가 있다. 단일 테스트의 경우 같은 코드를 반복해서 사용하거나 테스트 내에 배열을 선언해서 사용해야하는 경우가 있는데 이 때 JunitParams를 이용해서 테스트를 진행할 수 있다.
private static Object[] parametersForTestFree() {
return new Object[]{
new Object[]{0, 0, true},
new Object[]{100, 0, false},
new Object[]{0, 100, false},
new Object[]{100, 200, false},
};
}
@ParameterizedTest
@MethodSource("parametersForTestFree")
@Description("event가 free인지 확인합니다.")
void testFree(int basePrice, int maxPrice, boolean isFree) {
// JunitParams를 이용한 테스트 코드
// given
Event event = Event.builder()
.basePrice(basePrice)
.maxPrice(maxPrice)
.build();
// when
event.update();
// then
assertThat(event.isFree()).isEqualTo(isFree);
}
테스트 외부에 배열을 반환하는 메소드를 선언하고 @MethodSource annotation의 값으로 메소드를 넘긴다. 그리고 @ParameterizedTest annotation을 붙혀주면 배열값을 인자로 받아서 사용할 수 있고, 배열의 수만큼 테스트를 여러 번 진행하게 된다.