회고/TIL

웹 계층 개발 완료 그리고 테스트

KEEMSY 2023. 7. 31. 23:43

오늘은 드디어 내가 생각한 웹 계층 개발을 모두 마쳤다. 내가 생각한 테스트까지 모두 작성 완료하였다. 이전의 고민과 겪은 시련(?)들 덕에 남은 기능 개발 및 테스트는 그렇게 큰 문제 없이 개발 할 수 있었다. 하지만 개발을 하면서 고민이 안됬다는 것은 아니다.

 


ProductQueryController 개발

여러 값을 입력받을 수 있는 ProductCategory 를 활용한 조회 기능

 

어제 ProductQueryController 개발 사항들 중, 특정 Product 조회 기능에 대한 테스트 및 개발을 완료하고 또 기록까지 끝냈다. 그리고 남은 ProductCategory 를 활용한 Product 조회 기능을 오늘 개발 하였다.

 

이번 개발을 진행하면서, 느낀점은 쉬우면서도(?) 어려웠다.

 

쉽다고 느낀 부분은 그냥 내가 개발할 기능이 너무 간단하다는 것이다. 웹 계층을 개발하는 것이므로, 나는 웹계층만 신경쓰면된다. 신경써야하는 부분(책임)을 간단하게 이야기한다면, 입력 값을 잘 받고, 반환만 잘하면된다.

  • HTTP 요청을 자바 객체로 매칭하고, 출력을 처음과 반대로 HTTP로 매핑한다.

근데 내가 어렵다고 느낀 부분은 나머지 모든 부분이다. 이렇게말하고보니 어려웠다고 보는게 맞는 것 같기도.. 하다.. 나는 특히 입력 유효성 검사를 어디서 해야할 지 고민이 되었다. 유효성 검사의 책임에 관해 지난 다른 계층 개발 간 고민한 적이 있는데, 당시 유효성 검사 요소로는 필드값의 유효 여부(NotNull)만을 확인했었다. 하지만 이번 기능을 개발하면서 다른 유효성 검사가 필요함을 깨닫게 되었다.

 

 


유효하지 않는 ProductCategory 의 조회

 

유효하지 않는 ProductCategory 의 유효성 검사는 TrackProductListQuery 에서 책임지도록 나는 설계를 했었다. 입력 값이 유효하지 않다면, ProductDTOException 을 발생시키고, TrackProductListQuery 가 생성되지 않도록 만들었다.

 

TrackProductListQuery 의 일부분, TrackProductListQuery 생성 시, 유효성 검사를 진행한다.

 

하지만 개발을 하면서 첫번째 고민이 생겼다. 나는 입력 값으로 여러 ProductCategory 를 입력 받게하는데, 다수의 ProductCategory 중, 유효하지 않은 ProductCategory 가 여러개인경우 유효하지 않은 모든 정보를 같이 반환하는 것이 더 맞지 않을까? 하는 생각이들었다. 한번에 하나의 유효하지 않음을 알리는 것이 맞나? 하는 생각과 함께 말이다.

 

나는 이에 대하여, 전자를 채택하기로 하였다. 그 이유는 한번의 요청을 통해 잘못된 정보를 한번에 식별해주는 것이 맞다는 생각이 들었기 때문이다. 그리고 후자는 불필요한 요청을 만들어 내는 행동이라는 생각했다.

 

그리고 난 뒤 두번째 고민스프링에서는 GET  파라미터를 어떻게 받는거지? 하는 고민이 되었다. 스프링을 활용한 개발이 처음이라, 기초적인 부분임에도 불구하고 순간 멍.. 해졌었다. 또 이를 어떻게 테스트해야하지? 이게 고민 세트였다. 하지만 이 문제는 GPT를 통해 쉽게 해결할 수 있었다.

 

내가 작성한 해당 기능의 존재하지 않는 ProductCategory 조회 시 정상 에러 확인 테스트

정상 ProductCategory 를 통한 Product 조회 의 경우, 너무 길어 비교적 간략한 존재하지 않는 ProductCategory 를 사용한 경우의테스트를 캡쳐했다. 그런데 지금 보니깐 이 테스트는 깨지기 쉬운 테스트인것같다. message 부분이 잘못됬다. 지금 테스트에서는 단일 Category 를 검증했는데, 여러 카테고리일 경우를 커버하지 못한다. 수정해야겠다.

 

개발된 trackProduct 메서드

나는 이렇게 기능 개발을 마무리했다. 그런데 지금보니깐 메서드 명이 조금.... 개선의 여지가 많아보인다. 이 부분도 개선해야겠다..

 

 


ProductCommandController 개발

 

ProductQueryController 의 개발을 마치고, Product 개발의 마지막(?) ProductCommandController 개발을 시작했다. CommandController 에서는 상태를 변경하는 요청, Product 의 생성 및 수정 API 를 책임하도록 설계하였다.

 

그리고 오늘 대부분의 고민과 이슈는 CommandController 를 개발하면서 발생했고, 문제가 됬던 부분은 DTO 객체의 역직렬화 부분 이었다.

 

직렬화에서 인스턴스를 생성할 수 없다고 한다.

 

JSON 변환 과정 중, CreateProductCommand 객체를 생성할 수 없다 는 오류가 발생했다.

생성자가 없다고 한다..?

 

에러 메시지의 마지막에서는 생성자가 없다고 하였다. 나는 의문이었다.. 아니 나는 분명 생성자가 존재하는데..? 뭐지..?

 

CreateProductCommand 의 생성자 부분

 

 

나는 의문이 들었다. 왜 생성자가 있는데 없다고 하는거지? 일단 에러를 해결하기 위해, @AllArgsConstructor 를 붙여보았는데, 해당 에러는 사라졌다. 그리고 나는 다음 문제를 해결하기 위해 넘어갔다. 이 어노테이션이 다른 기능에 영향을 줄 수있지 않은가? 하는 고민은 이전에 작성한 CreateProductCommandTest 를 포함한 전체 테스트에 이상이 없음을 확인했기 때문이다. 역시.. 테스트가 아주 훌륭하다.

 

하지만 문제는 여기서 끝나지 않았다. CreateProductCommand 의 price 필드 값을 Money 객체로 역직렬화를 할 수 없었다. 처음에는 이것이 왜 안되는 것일까... 궁금하고.. 또 모르겠어서 GPT에게 물어보니, 이는 자동으로 역직렬화가 되지 않는다고 한다.

 

생각해보면 입력값으로 오는건데, Java 객체로 매핑을 또다시 한다는게 가능한가? 싶다. 그래서 해당 부분을 모두 수정했다.

수정된 부분, price 필드가 BigDecimal 로 수정되었다.

이 부분을 수정하면서, 테스트의 위엄을 또다시 느낄 수 있었다. 오류가 발생하는 곳을 모두 수정하고, 맘편히 개발을 계속했다. 근데 고민은 얼마지나지않아 바로 또다시 생겼다.

 

테스트에서는 이 Json 입력 값을 body에 어떻게 할당해야하지? 하는 고민에 빠졌다. 처음에는 HashMap 을 활용하여 content 를 만들고, ObjectMapper 를 통해 JSON String 으로 변환하고, 해당 변환 값을 content 로 지정하였다. 근데 이것이 CreateProductCommand 객체로 된다는 것을 확신할 수 없었다. 

 

완성된 createProductTest의 모습

 

나는 해당 고민을 GPT에게 이야기했고, GPT는 아주 친절하게 더 좋은 방법을 알려주었다. 나는 ObjectMapper 의 writeValueAsString() 메서드를 사용했는데, 이 메서드는 객체를 JSON String 으로 만들어 준다. 그리고 이말은 즉슨, CreateProductCommand 객체 또한 JSON String 으로 변환이 가능함을 의미했다. 이렇게 하니 아주 내망에 쏙 드는(?) 테스트를 작성할 수 있었고, 기능을 검증하고 해당 기능을 마무리 할 수 있었다.

 

나머지 updateProduct 의 경우도 createProduct 와 크게 다른 것이 없었다. UpdateProductCommand 또한 price 필드가 잘못됬었고, 같은 인스턴스를 생성할 수 없다는 에러가 발생했다. 그리고 같은 방법을 통해 문제를 해결했다.

 

이렇게 나는 내가 처음 목표한 Product 도메인의 웹계층 개발을 완료하였다.

 


벌써 휴가철이라고 한다. 그리고 부모님은 여름 휴가로 시골에 내려가셨다. 나도 가고싶었지만.. 지금은 이것을 더 하고싶었다. 부모님 휴가기간 모두 시골에 계시는 것은 아니니깐, 하루정도는 부모님과 함게 쇼핑도하고 식사도 해야겠다.

 

원래 계획이라면.. 지금은 Order 도메인을 다 마치고, 이력서까지 반영하고서 슬슬 이력서도 넣고 면접준비를 해야하는데, 너무 늦어진것같다. 비록 늦었지만 더 확실하게 해야겠다. 그래도 부족한 부분이 많겠지.. 부족한 부분을 스스로 채워나갈 수 있는 멋진 개발자가 되어보자!! 내일은 PR 작성하고 리뷰를 요청해야지! 그리고, Order 가즈아 !!!

 

잊지말자, Product 문서정리, Issue 개발!!

 

728x90