본문 바로가기

Spring

컨트롤러 테스트에 인증/인가가 들어있는 경우

  • @SpringBootTest를하면 모든것이 다 빈으로 등록이 되니까 자연스럽게 테스트가 됨
  • @WebMvcTest 사용하면 컨트롤러만 빈으로 등록이되서 ArgumentResolver랑 JwtFilter 를 수동으로 등록을 해줘야 작동을 한다!
  • JpaMetamodelMappingContext : Spring Data JPA의 자동 설정 중 하나인 JpaMetamodelMappingContext가 없어 생기는 빈 등록 예외를 방지하기 위해서 주입
  • 또한 컨트롤러는 Argument Resolver랑 Converter 같은걸 거치니까 새로운 객체가 생겨서 eq로 내용이 동일한지 확인해줘야함

 

기존에 @WebMvcTest를 사용했는데 수동으로 등록하지않았다면 AuthUser에 필드가 다 null이었음 ⇒ any()를 써버리니까 통과가 되었던 것!

 

결론 : 그래서 Filter랑,Argument Resolver를 등록하고 하니까 AuthUser가 정상적으로 만들어지고 컨트롤러 테스트가 잘 통과 된다!

@WebMvcTest(AlarmController.class)
@TestPropertySource(properties = {
        "jwt.secret.key=5Gk6hibHDtKLFVk4NdBX039rvehSLNjfKsdXpm/pHsU="
})
@Import({JwtUtil.class, AuthUserArgumentResolver.class, JwtFilter.class})
class AlarmControllerTest {

    @Autowired
    MockMvc mockMvc;

    @MockitoBean
    JpaMetamodelMappingContext jpaMetamodelMappingContext;

    @MockitoBean
    AlarmService alarmService;

    @Autowired
    JwtUtil jwtUtil;

    AlarmHistories histories1;
    AlarmHistories histories2;

    @BeforeEach
    void setUp() {
        histories1 = AlarmHistories.of(
                "회원님의 글에 댓글이 달렸습니다",
                1L,
                AlarmType.COMMENT
        );
        ReflectionTestUtils.setField(histories1, "id", 1L);
        ReflectionTestUtils.setField(histories1, "createdAt", LocalDateTime.now());

        histories2 = AlarmHistories.of(
                "회원님의 글에 댓글이 달렸습니다",
                1L,
                AlarmType.COMMENT
        );
        ReflectionTestUtils.setField(histories2, "id", 2L);
        ReflectionTestUtils.setField(histories2, "createdAt", LocalDateTime.now());
    }

    @Test
    public void 알람_내역을_페이징을_이용하여_조회한다() throws Exception {
        // given
        int page = 0;
        int size = 10;
        int totalElement = 2;
        int totalPages = 1;

        Pageable pageable = PageRequest.of(page,size);

        Long userId = 1L;
        UserRole userRole = UserRole.PATIENT;
        AuthUser authUser = AuthUser.of(userId, userRole);

        String accessToken = jwtUtil.createToken(userId, userRole);

        List<AlarmHistories> alarmHistories = new ArrayList<>();
        alarmHistories.add(histories1);
        alarmHistories.add(histories2);
        List<AlarmResponse> alarmResponses = AlarmResponse.toAlarmResponse(alarmHistories);

        PageInfo pageInfo = PageInfo.builder()
                .pageNum(page)
                .pageSize(size)
                .totalElement(totalElement)
                .totalPage(totalPages)
                .build();

        PageResult<AlarmResponse> pageResult = new PageResult<>(alarmResponses, pageInfo);

        given(alarmService.findAlarms(refEq(authUser) // 필드값 비교
                , argThat(p -> p.getPageNumber() == pageable.getPageNumber() && p.getPageSize() == pageable.getPageSize()))) // 페이징 객체 값만 비교
                .willReturn(pageResult);

        // when & then
        mockMvc.perform(get("/api/v1/notifications")
                        .param("page", "0")
                        .param("size", "10")
                        .header("Authorization", accessToken))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[0].id").value(histories1.getId()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[0].content").value(histories1.getContent()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[0].alarmType").value(histories1.getAlarmType().name()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].id").value(histories2.getId()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].name").value(histories2.getContent()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data[1].alarmType").value(histories2.getAlarmType().name()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.page.pageNum").value(page))
                .andExpect(MockMvcResultMatchers.jsonPath("$.page.pageSize").value(size))
                .andExpect(MockMvcResultMatchers.jsonPath("$.page.totalElement").value(totalElement))
                .andExpect(MockMvcResultMatchers.jsonPath("$.page.totalPage").value(totalPages));
    }

}