barded
[무물] 2-3. 계층별 단위테스트 - Controller 본문
Controller 계층의 단위 테스트 역할
Controller 계층의 단위 테스트는 Service를 MockBean객체로 주입받은 후, 호출하여 예상한 결과가 맞는지 확인하면 된다.
FromMeControllerTest
@ActiveProfiles("local")
@WebMvcTest(FromMeController.class)
@MockBean(JpaMetamodelMappingContext.class)
class FromMeControllerTest {
final String USERNAME = "USERNAME";
@Autowired
MockMvc mockMvc;
@MockBean
FromMeService fromMeService;
@MockBean
UserDetailService userDetailService;
@BeforeEach
void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new FromMeController(fromMeService))
.setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()).build();
}
@Test
@DisplayName("FromMe 피드")
public void getFromMeFeed() throws Exception {
//given
List<PostResponseDto> postResponseDtos = List.of(
new PostResponseDto(1L, "test", "test", null, 1L, null, 0L, null, 0L, false, LocalDateTime.now()),
new PostResponseDto(2L, "test", "test", null, 1L, null, 0L, null, 0L, false, LocalDateTime.now())
);
User user = new User("test", "test", null);
given(userDetailService.getUser(1L)).willReturn(new UserDetailDto(1L, USERNAME));
given(fromMeService.getFromMeFeed(any(UserDetailDto.class), any(String.class), any(Pageable.class))).willReturn(postResponseDtos);
//when
ResultActions actions = mockMvc.perform(get("/fromme")
.param("username", USERNAME)
.param("pageNumber", "0")
.param("pageSize", "10")
.with(SecurityMockMvcRequestPostProcessors.user(user)) // 모의 인증된 사용자 주입
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON))
.andDo(print());
//then
actions.andExpect(status().isOk())
.andExpect(jsonPath("$[0].id").value(1L));
}
}
Controller 계층의 Annotation들
- @ActiveProfiles("local"):
- 테스트가 실행될 때 "local" 프로필을 활성화함으로써, 개발 환경에 특화된 설정을 적용함.
- @WebMvcTest(FromMeController.class):
- Spring MVC에 집중할 수 있는 테스트 환경을 제공함. 여기서는 FromMeController에 대한 웹 계층만을 테스트하기 위해 사용됨.
- @MockBean(JpaMetamodelMappingContext.class):
- JPA 메타모델을 위한 목(Mock) 객체를 생성함으로써, 실제 데이터베이스를 사용하지 않고 테스트를 진행할 수 있게 함.
- @Autowired:
- Spring의 의존성 주입 기능을 사용하여 MockMvc 인스턴스를 자동으로 주입함.
- @MockBean:
- 테스트에서 사용될 서비스(FromMeService, UserDetailService)의 목(Mock) 객체를 생성함. 이를 통해 실제 서비스 로직을 실행하지 않고도 서비스의 행동을 모의할 수 있게 함.
- @BeforeEach:
- 각 테스트가 실행되기 전에 공통적으로 수행해야 할 작업을 정의함. 여기서는 MockMvc 인스턴스를 설정함.
- @Test:
- 실제 테스트를 수행하는 메서드임을 나타냄.
- @DisplayName("FromMe 피드"):
- 테스트 결과 보고서에서 보여질 테스트의 이름을 "FromMe 피드"로 지정함.
Controller의 Given-When-Then
- given:
- 테스트를 실행하기 전에 필요한 사전 조건을 설정함. 이 경우에는 특정 사용자의 정보와 "FromMe 피드"를 가져오기 위해 필요한 가짜(PostResponseDto 리스트) 응답을 준비함. 또한, userDetailService.getUser(1L)와 fromMeService.getFromMeFeed 메서드가 호출될 때 반환할 값을 지정함으로써, 실제 서비스 로직을 실행하지 않고도 테스트가 가능하게 함.
- when:
- 실제로 테스트하고자 하는 행동을 실행함. 여기서는 "/fromme" 엔드포인트에 HTTP GET 요청을 보내는 것이며, 이 요청에는 사용자 이름, 페이지 번호, 페이지 크기를 파라미터로 포함함. 또한, SecurityMockMvcRequestPostProcessors.user(user)를 사용해 모의 인증된 사용자 정보를 요청에 주입함.
- then:
- when 단계에서 실행한 행동의 결과를 검증함. 여기서는 응답 상태 코드가 200(OK)인지 확인하고, JSON 응답 본문의 첫 번째 항목의 id가 1L(기대하는 값)인지 확인함으로써, API가 올바르게 작동하는지 검증함.
setUp() 메서드 설명
@BeforeEach로 표시된 setUp 메서드는 각 테스트가 실행되기 전에 자동으로 실행됨. 이 메서드에서는 MockMvc 인스턴스를 초기화하는 작업을 수행함. 구체적으로, FromMeController의 인스턴스를 생성하고, 이를 사용하여 MockMvcBuilders를 통해 MockMvc 인스턴스를 설정함. 여기서 fromMeService를 FromMeController의 생성자에 주입하여, 실제 서비스 로직을 모의로 대체할 수 있게 함.
또한, setCustomArgumentResolvers 메서드를 통해 PageableHandlerMethodArgumentResolver를 커스텀 인자 해석기로 설정함. 이는 Spring MVC에서 페이지네이션과 관련된 파라미터를 처리할 수 있게 해줌. 마지막으로, build() 메서드를 호출하여 설정을 마치고 MockMvc 인스턴스를 생성함. 이렇게 설정된 MockMvc 인스턴스는 테스트 중에 컨트롤러의 요청을 모의로 처리하는데 사용됨.
[무물] 2-1.계층별 단위테스트 - Repository
[무물] 2-3. 계층별 단위테스트 - Controller
[무물] 3-1. 통합테스트 MockMvc vs. WebTestClient vs. TestRestTemplate
'프로젝트 > 무물' 카테고리의 다른 글
[무물] 3-2. 통합테스트 (0) | 2024.06.06 |
---|---|
[무물] 3-1. 통합테스트 MockMvc vs. WebTestClient vs. TestRestTemplate (0) | 2024.06.06 |
[무물] 2-2. 계층별 단위테스트 - Service (0) | 2024.06.06 |
[무물] 2-1.계층별 단위테스트 - Repository (0) | 2024.06.06 |
[무물] 1. 단위테스트 / 통합 테스트 란? (1) | 2024.06.06 |