[TIL] Today I Lerned - 230110

2023. 1. 10. 23:05기록/TIL

[TIL] Today I Lerned - 230110

 

230110 기록

 

알고리즘

 

[Python] 프로그래머스 lv1 - 푸드 파이터 대회 (tistory.com)

 

[Python] 프로그래머스 lv1 - 푸드 파이터 대회

[Python] 프로그래머스 lv1 - 푸드 파이터 대회 코딩테스트 연습 - 푸드 파이트 대회 | 프로그래머스 스쿨 (programmers.co.kr) 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래

skyriv312079.tistory.com

 

 

Test

 

Controller Test 작성, 검색을 하고 찾아보다가 안돼서 배운 내용을 정리하려 한다.

 

  • JpaAuditingHandler 오류
더보기

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaAuditingHandler': Cannot resolve reference to bean 'jpaMappingContext' while setting constructor argument

이전에 SpringApplicaiotn code 파일에 @EnableJpaAuditing에서 비롯된 문제

 

  • @EnableJpaAuditing
    • Spring Data Jpa에서 시간의 관한 값을 자동으로 넣어주는 기능
    • 해당 기능을 SpringBootApplicaion에서 사용하고 있기에 Test 하려는 Controller 쪽에서도 해당 기능에 대해 언급을 해줘야 한다
    • 이때 @MockBean(JpaMetamodelMappingContext.class)를 해당 Test class code에 기입해주면 된다.
    • 이때 TEST의 경우 실제 기능이 아닌 Mock이란 가짜 Bean을 선언하여 해당 Bean을 처리해야 한다. 

  • 통합 / 단위 테스트에 사용되는 어노테이션
    • 처음 컨트롤러에서 사용되는 어노테이션을 생각할 때 되는대로 사용하다 보니 통합 / 단위 테스트에 사용되는 어노테이션을 혼용해놓고는 안된 적이 있었다. 그렇기에 통합 / 단위 테스트 - controller의 부분만 어떤 어노테이션이 존재했는지 작성하려 한다.
    • 통합
      • 해당 어노테이션들은 통합 테스트 - controller , service , repository 등 모든 부분의 테스트를 진행할 때 사용
      • @AutoConfigureMockMvc
      • @SpringBootTest 
    • 단위
      • 해당 어노테이션들은 단위테스트 - controller 부분에서 한정하여 테스트 코드를 작성할 때 사용 
      • ExtendWith()
        • 확장 기능 제공을 위한 역할의 어노테이션
      • WebMvcTest
        • spring mvc component에 초점을 두고 테스트하기 위해 사용
    • controller test의 기능
      • 기존의 컨트롤러 테스트를 잘못 이해하고 있었다. 기존의 경우 controller에서 service로 메서드를 호출하고 요청에 맞춰서 값이 불려 오면 controller에서 반환을 하기에 이 부분을 구현해야 한다고 생각을 했다.
      • 튜터님과 이야기를 하면서 나온 결론은 이런 반환값을 초점을 두면 해당 테스트 코드의 방향은 단위 테스트가 아닌 통합 테스트 관점으로 빠진다는 것을 알았다.
      • 컨트롤러 단에서의 단위테스트는 다음과 같다
        • 기존에 RESTFUL 한 설계를 통해 해당 요청에 따른 Status 코드를 세분화를 하였으면, 원하는 값(given에서 주어진 값)에 따라 알맞은 Status code를 반환해야 한다는 것
      • 만약 컨트롤러 테스트에서 시큐리티의 존재로 인해 에러가 존재할 수 있다.
더보기

    Session Attrs = {org.springframework.security.web.csrf.HttpSessionCsrfTokenRepos itory.CSRF_TOKEN=org.springframework.security.web.csrf.DefaultCsrfToken@55 d99 dc3, SPRING_SECURITY_CONTEXT=SecurityContextImpl [Authentication=UsernamePasswordAuthenticationToken [Principal=org.springframework.security.core.userdetails.User [Username=user, Password=[PROTECTED], Enabled=true, AccountNonExpired=true, credentialsNonExpired=true, AccountNonLocked=true, Granted Authorities=[]], Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[]]]}

해당 경우에는 with(csrf())를 get / post 요청이 들어가는 경우 옆에 붙여주고, 해당 요청은 Security 필터를 통과하였다는 

@WithUserDetails를 넣어주면 통과가 된다.

 

  • MockMvc 
    • perform -  요청과 반환 타입에게 다음 동작에 대한 체인을 걸어주는 역할
      • Get / Post 같은 요청의 형식 지정 가능
    • contentType -  해당 요청에서 들어오는 데이터가 어떤 타입인지 지정
    • content  - 요청에서 들어오는 값을 의미 - ex : requestDto
      • 이때 json타입으로 값이 들어오면 spring에서는 ObjectMapper를 통해 자동으로 파싱 하여 requestDto에 값을 넣어주지만 test에서는 직접 objectMapper로 넣어주는 과정이 있어야만 해당 값이 매치가 됨.
    • andExpect -  예상되는 값 지정하기 - Assertions 느낌 

작성된 UserController Test code


@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = UserController.class)
@MockBean(JpaMetamodelMappingContext.class)
class UserControllerTest {

    /***
     * 컨트롤러 테스트
     * REST API status 코드 세분화
     * validation - request 데이터에 맞춰서 상태코드를 반환하는 것을 테스트 ★★★★★
     * security에서도 맞춰서 controller 테스트에서 반응할 수 있도록
     */
    @Autowired
    MockMvc mockMvc;

    @Autowired
    ObjectMapper objectMapper;

    @MockBean
    UserService userService;

    @Test
    @WithUserDetails
    void signup() throws Exception {
    	//given
        SignupRequestDto requestDto = SignupRequestDto.builder().username("asdf123456").password("asdasfsfsa123").admin(false).adminToken("").build();

		//when, then
        mockMvc.perform(post("/user/signup").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsBytes(requestDto)).with(csrf()))
                .andExpect(status().isCreated());

    }

    @Test
    @WithUserDetails
    void login() throws Exception {

        mockMvc.perform(post("/user/login"))
                .andExpect(status().is4xxClientError());
//                .andExpect(content().)
    }


}

 

 

'기록 > TIL' 카테고리의 다른 글

[TIL] Today I Lerned - 230112  (0) 2023.01.12
[TIL] Today I Lerned - 230111  (0) 2023.01.11
[TIL] Today I Lerned - 230109  (0) 2023.01.09
[TIL] Today I Lerned - 230106  (0) 2023.01.06
[TIL] Today I Lerned - 230105  (0) 2023.01.06