
Spring 애플리케이션에서 각 레이어는 명확한 책임 분리를 통해 유지보수성과 테스트 가능성을 향상시키며, 각 레이어에 적합한 테스트 전략을 적용할 수 있습니다. 예를 들어, Controller Layer는 클라이언트 요청을 처리하고 Service Layer를 호출하며, Service Layer는 비즈니스 로직을 처리하고 Repository Layer는 데이터 접근을 담당합니다. 아래는 Controller, Service, Repository 레이어 각각의 테스트 방법과 그 전략을 설명합니다.
역할:
테스트 전략:
예제 코드:
@DisplayName("차량 입차 요청을 처리한다.")
@Test
void issueParkingTicket() throws Exception {
// given
VehicleDto request = new VehicleDto("ABC-1234");
// when // then
mockMvc.perform(
post("/api/v1/parking/tickets")
.content(objectMapper.writeValueAsString(request))
.contentType(MediaType.APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk());
}
역할:
테스트 전략:
예제 코드:
@Autowired
private ParkingService parkingService;
@Autowired
private ParkingRepository parkingRepository;
@DisplayName("새로운 차량이 입차되면 주차 티켓이 생성된다.")
@Test
void issueParkingTicket() {
// given
Vehicle vehicle = new Vehicle("ABC-1234");
// when
ParkingTicket ticket = parkingService.issueTicket(vehicle);
// then
assertThat(ticket).isNotNull();
assertThat(ticket.getLicensePlate()).isEqualTo("ABC-1234");
}
역할:
테스트 전략:
예제 코드:
@Autowired
private ParkingRepository parkingRepository;
@DisplayName("등록된 차량의 주차 티켓을 조회한다.")
@Test
void findParkingTicketByLicensePlate() {
// given
ParkingTicket ticket = new ParkingTicket("ABC-1234");
parkingRepository.save(ticket);
// when
Optional<ParkingTicket> foundTicket = parkingRepository.findByLicensePlate("ABC-1234");
// then
assertThat(foundTicket).isPresent();
assertThat(foundTicket.get().getLicensePlate()).isEqualTo("ABC-1234");
}
사이드 프로젝트 중, "서비스 테스트에서 왜 Mock만 사용하냐? 실제 객체를 사용하는 기준은 무엇이냐?"라는 질문을 팀원에게 받은 경험이 있습니다. 이 질문을 통해 각 계층에서 Mock과 실제 객체의 사용 기준을 재검토하게 되었고, 이를 기반으로 테스트 전략을 구체화할 수 있었습니다. 이러한 기준은 각 레이어의 책임을 분리하고 테스트 목적에 맞는 적합한 방법을 선택하는 데 도움을 주었습니다.
이 질문을 계기로 테스트 방법에 대한 강의를 들었고, 해당 강의에서는 다음과 같은 기준으로 Mock과 실제 객체 사용을 구분하였습니다:
Mock 사용:
실제 객체 사용:
이 기준을 통해, 각 계층에서의 테스트 전략을 더 명확히 구분하고, 필요한 수준의 검증을 적절히 수행할 수 있었습니다.
위의 테스트 전략을 통해 각 레이어에 적합한 검증을 수행함으로써, 애플리케이션의 신뢰성을 높이고 유지보수성을 향상시킬 수 있습니다. Controller는 Mock 객체로 경량화된 테스트를 수행하고, Service와 Repository는 실제 객체를 사용하여 더욱 깊이 있는 검증을 진행합니다. 또한, Mock과 실제 객체의 사용 기준을 명확히 함으로써 테스트 설계의 명확성을 높였습니다.
📌 이 글은 TDD 강의를 학습한 내용을 바탕으로 재구성하였습니다. 문제가 되는 부분이 있다면 수정하겠습니다.