티스토리 뷰

12.10) 오늘 하루동안 eat-together 게시글 관련 기능 구현하며 경험한 것들 with 티버

ATDD 프로세스에 대해

  • 문제 인식
    • ATDD를 하고싶어서 가장 큰 도메인 모델인 Article을 잡고 시작. 인수테스트를 통과시키기 위해 제일 먼저 테스트를 짜고 깡통 Controller를 만들었다. 여기까진 괜찮은데, Shop, Order, Menu, Item 등 관련된 도메인 모델들을 갑자기 한번에 만드려니 꼬이기 시작했다. 여기저기에서 문제가 많이 발생했는데, 특히 관계매핑 관련해선 더욱 힘들었다. 게다가 각 모델들을 객체지향적으로 만들고있다는 느낌은 안들었고, Article에 필요한대로 급하게 끼워넣으려 만드는 느낌이 들었다.
    • 방향을 바꿔보기로 했다. Article을 잡았으면 깡통을 만들고 이제 그안을 채우기 위해, Shop 도메인을 잡고 다시 in→out으로 구현해보기로 했다. 근데 이게 과연 ATDD 개발이 맞는가?
  • Brown's Said
    • 우린 관계매핑이 너무 빨랐다. 깡통으로 진행하다가 관계매핑은 필요한 시점에 만든다.
    • 전반적으로 '레이어' 관점으로 구현을 진행
  • 반성 (?) + 개선방안
    • 티버도 그렇게 생각했을진 모르겠지만, 난 Controller 테스트와 Acceptance 테스트를 너무 비슷하게 생각했다. 인수 테스트를 하자고하면서, 사실은 컨트롤러 테스트 또는 단순히 CRUD 테스트만 하고있었던 것.
    • 난 개인적으로 고정관념이 있었다. 테스트는 최대한 짧아야할것만 같고(물론 긴것보단 짧은게 낫긴하지만), 한 테스트는 한 가지 기능만 수행하고 검증해야할것같은 편견.
    • 브라운의 테스트 예시를 들으며 오해를 풀수있었다. 인수테스트니까 '사용자의 시나리오'를 검증하는것이 중요하다.
    • 물론 인수테스트의 범위를 어디까지 잡을것인가에 대해선 논의도 많고 정답도 없지만, 브라운과 나 역시도 상태확인만으론 불충분하다고 느꼈다. save라면 실제로 데이터가 추가됬는지 확인하는게 안전할것같다.
    • Read 테스트는 응답으로 데이터가 넘어오므로 이를 이용해 상태뿐만아니라 원하는 데이터라 리턴되는지까지 쉽게 확인할수있었다. 반면 추가나 삭제는 별도의 데이터를 리턴하지않게 구현하면, 응답으로 바로 확인할 방법이 없었다. 이때, 이렇게 끝나는게 아니라 다시한번 콜을 쏴서 추가/삭제됬는지 확인하면 되는거였다. 고정관념을 버리고.
    • 글을 쓰다보니 또 CRUD에 집착하게 되는데, 한번 더 상기하면 "인수테스트는 사용자 스토리를 검증하는게 목표다"
  • // Todo : Acceptance Test vs Controller Test 차이를 고민해보자

모듈을 2개로 분리한 경우, 양쪽 모두에서 사용하는 클래스는 어떻게 관리하는가?

  • 문제 인식
    • 프로젝트 구상 초반에 Aiden에게서, 가게 관련 기능은 별도 모듈 및 서버로 분리해보자는 의견이 나왔다. Article을 포함한 메인 프로젝트는 가게 서버에게 API를 쏴서 데이터를 주고받는 방식으로.
    • Shop 도메인을 구현하다가 의문이 들었다. Menu 객체는 Article쪽과 Shop쪽 모두 사용한다. 어떻게 관리해야할까?
    • 처음엔 같은 Menu 클래스이므로 어떻게 정합성을 유지할까 의문이 들었다. 좀더 생각해보니, 엄밀히보면 다른 객체니까 양쪽에서 분리해서 각자 Menu를 들고있는게 당연하다고도 생각이 들었다.
  • Brown's Said
    • 공통으로 관리하고싶다면, Menu도 빼야지, 별도 모듈로. 그런데 과연 그렇게까지 하는게 맞을까? 정답은 없다. 엔지니어링의 관점에서 각 상황에 맞게 유지보수하기 편하고 효율적인 방향을 택하라고 들었다.
    • 듣고 생각해보니, 지금 프로젝트 사이즈에선 과할수도 있다는 생각이 들었다. 하지만 Aiden도 별도의 서버에 API 콜을 쏴서 로직을 구성해보는 경험을 해보자는 차원에서 제시한 의견이니, 해봐도 나쁘진 않을것 같았다. 일단 지금 상황에선 시간이 없고 다른 우선순위들이 있어 보류.

@WebMvcTest + MockMvc / @SpringBootTest + WebTestClient

  • 조합으로 많이들 쓴다. 무조건 그래야하는건 아니지만
  • 전자는 Controller 테스트에 적합
    • mock을 사용해 대부분 Bean을 수동으로 설정해줘야한다.
  • 후자는 Acceptance 테스트에 적합
    • 이때 주의할 점. WebTestClient는 webflux를 쓰므로 기존 Spring Mvc 구조를 못 쓴다. DispatcherServlet 쓰는 Controller, Service 등 우리가 기존에 만들던.
    • (그래서 우리 Rest Docs 이슈가 생겼던 것 - 잘되던 Rest Docs가 깡통 컨트롤러에 우리가 만든 빈 클래스들 끼우면 Application Context 에러 터지던 이슈)
    • 그래서 이 경우 정 WebTestClient를 쓰고싶으면, BindToServer() 를 사용해야한다. IP로 직접 서버 때려서 WebTestClient를 초기화.

B코치의 또다른 Tip

  • jBehave 라는게 있다. given-when-then 방식으로 인수테스트 가능. 알아보자.
  • Text Fixture를 만드는 방법으로, data.sql 방식 vs 직접 만든 비즈니스 로직을 태워 만드는 방식
    • 정답은 없다. 개인적으로 후자를 선호.

Service에 필드가 많아진다면 ?

@OneToMany List<?> 상황에서 LazyInitializationException 예외와 해결방안

JPA 양방향 순환참조 문제

  • 검색하면 관련 이슈 많음
  • 크게 다음과 같은 3가지 해결방안이 있는듯하다. 참고
  • 블로그 중 무조건 주인객체에 @JsonManagedReference를, 하인객체에 @JsonBackReference를 붙이라는 곳도 있는데, 그보단 @JsonBackReference가 붙은쪽이 직렬화에서 제외되니 이를 고려해서 적절히 사용.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함