개발로그(003)

원태연·2022년 8월 30일
0

개발로그

목록 보기
3/4
post-thumbnail

2022년 08월 30일(화)

✅ 오늘 한 일

Programmers 문제 풀기
FIKA Test 환경 설정 및 테스트 추가
알고리즘 스터디

👀 발생했던 오류

  1. 현재 데이터가 들어가 있는 프로젝트에 영향을 주지 않으면서, Test 코드를 설정하기 위해 test용 Property를 구성했다. Spinrg Project에는 main과 test 패키지가 있는데, test path에 resource/application.yml을 생성하면, Test 동작은 해당 설정을 따라간다.

    Test용 DB를 위해 H2를 사용했고, 그래서 main과 다르게 profile 설정을 하였다.

    2가지 문제가 발생했다. @SpringBootTest를 하면, 모든 Bean정보가 등록되는데, 이때 Amazon S3 설정도 해주어야 하기 때문에 (test)application.yml만으로는 실행이 되지 않았다. 민감한 정보이다 보니 다로 분리하여 .gitignore에 추가했고, 이를 include하는 형식으로 진행했다.

    Test 코드에선 또 RDS를 건들여야 하는 메서드가 있어서 data라는 다른 DBConncetion설정을 가진 property를 추가하였고, 동일하게 S3를 위해 이를 include하였다.
    그리고 다음과 같은 오류가 발생했다
    org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property 'spring.profiles.include' imported from location 'class path resource

    원인은
    application-data.yml --include--> application-test.yml이 문제였다.
    application.yml을 기본으로 동작하는 프로젝트에서, 다른 설정을 위해 @ActiveProfiles("data")을 통해 profile을 직접 설정해주었더니, include하는 profile을 찾지 못하는 것이었다. 해결은.. application-test의 내용을 data에 직접 추가하고 include를 삭제하니 잘 동작하였다.

  2. WebTest 구성
    독립적으로 동작하는 Web API Test를 구성하려고 했다. 그러기 위해선 @SpringBootTest가 필요했고(JPA를 통한 데이터 저장이나 조작이 필요했음), @BootstrapWith를 중복으로 포함한 @WebMvcTest를 선택할 수 없었다. Configuration error: found multiple declarations of @BootstrapWith for test class java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class 에러 발생

    간편하고 빠른 mockMvc를 사용하기 어려워졌고, restTemplate을 사용했다. 여기서 문제는, 안드로이드와 통신하기 위해 만들어둔 매우 깊게 심어진 응답 형태였다.
    ResponseEntity<ApiResponse<Object>>
    이때, xxxForObject(url, {응답받을 객체}.class)를 사용해야 하는데, 내가원하는 타입으로 매핑이 불가능했다.
    런타임 시에는 generic의 타입 정보가 사라져 지정한 객체로 응답하지 않고 Object클래스로 응답하더라.. 그리고 xxxForObject는 T에 Object가 넘어가면, LinkedHashMap으로 매핑해버린다
    RestTemplate이 jackson ObjectMapper를 사용하고 있기 때문이다

    그럼 어떻게 구성할까 더 찾아보니 다음과 같은 솔루션을 얻었다
    ParameterizedTypeReference을 구성하여 typeToken을 넘겨주는 것이다. 런타임시 Type erasure로 인해 사라지는 타입을 정해주면 된다. Spring에서 제공해주는 ParameterizedTypeReference를 통해 타입정보를 설정해주는 것이다.

    이런 형식(?)은 RestTemplate에서 자주 사용되고, 익명 클래스로 사용한다고 한다. 또, xxxForObject처럼 class<T>로 응답을 넘기는 메서드를 사용하지 말고, ParameterizedTypeReference<T>를 사용할 수 있는 exchange 메서드를 사용하자

  3. FIKA API 연결 시 Kakao login
    클라이언트에서 kakao login 완료 후, 발급받은 AccessToken을 서버로 요청한다
    서버는 요청 받은 AccessToken으로 카카오에 요청하여 사용자 정보를 받는다. 이때 응답하는 사용자 정보에서 Email을 정규 표현식을 통해 추출하고, 이 이메일로 회원가입을 시키게 했다.

    문제는 이메일이 항상 넘어오지 않는 경우가 있었다. 이메일 사용권한이 선택이었기 때문에, 정규표현식으로 추출한 Email을 찾을 수가 없었다. Kakao 비즈를 등록하여 이메일 권한을 필수로 변경하여 수정하였지만, 굉장히 위험한 방식이었던 것 같다. 필수, Unique한 데이터로 가입을 시켰어야 했는데 안일하게 생각했던 것 같다.

🎓 배운 점

  1. Test 환경설정. /test에선 또 다른 Profile을 설정 할 수 있고, 덕분에 여러 데이터베이스 설정할 수 있다. 그리고 독립적인 테스트에 대해선 조금 고민이 필요할 수 있을 것 같다. Contorller(API) 테스트에서 JPA까지 개입하는 게 좋은 지 고민해보자.

❗️앞으로 알아보면 좋은 것

  1. JPA Basic 강의 계속 듣기
  2. 독립성을 가진 테스트를 위해 deleteAll()을 매번 하는데, 여러개가 매핑된 하나의 Entity에 대한 테스트를 수행하면 연관된 Entity repository도 모두 deleteAll()을 해야한다는 이슈가 생긴다. 좋은 설계인지 의심해볼 필요가 있음... 혹은 DB자체를 ddl-auto : create처럼 비울 수 있는 방법이 있는지 찾아보자
profile
앞으로 넘어지기

0개의 댓글