이번에는 TDD를 기반으로 하는 단순한 API 코드를 작성하는 내용을 다루고자 한다.
우선 TDD가 무엇인지 생소한 분들이 있을 것이다.
TDD란 Test Driven Development의 약자로 ‘테스트 주도 개발’이라는 방법론을 말한다.
간단히 말해서 테스트코드를 작성하면서 자연스럽게 프로덕트 코드를 만들어내는 일련의 과정이라고 생각하면 된다.
그렇다고 단위테스트를 만드는 것 자체가 TDD의 목적은 아니며,
테스트코드를 바탕으로 안정적인 코드 리팩토링을 진행함에 그 목적이 있다고 봐야 한다.
가령, 우리가 회원 목록을 조회하는 기능을 개발했다고 가정해보자.
기존의 회원은 주민등록 번호가 PK였다고 가정하자.
그런데 개인정보보호법에 의거하여 주민등록번호를 마스킹 처리를 해야하게 되었다.
그렇다면 기존에 PK로 사용하던 주민번호를 대처하기 위한 대체키를 작업하게 될 것인데, 이럴때 사이트의 레거시 소스가 방대하다면 수정을 하면서 계속해서 사이드 이팩트에 시달리게 된다.
이럴때 기능단위로 테스트코드가 있다면 어떨까?
테스트코드를 바탕으로 사이드 이팩트의 범위를 어느정도 가시적으로 확인이 가능하게 된다. 그리고 이를 통해서 사이드이팩트를 미연에 예방하면서 안정적인 리팩토링을 수행할 수 있는 구조가 되는 안전장치가 되는 셈이다.
이러한 이유 말고도 많은 장점이 있는데, 이 부분은 별도의 포스트에서 설명하기로 하고
우선 구현하는 기능에 대해서 간략히 소개를 하겠다.
이전에 완성한 gradle 프로젝트를 빌드하여 실행을 한번 해보자.
스프링부트 어플리캐이션을 실행하기 위해서는 해당 어플리캐이션이 생성하는 main을
실행해야 한다.
실행하면 아래와 같은 콘솔이 출력되면서 기본포트 8080에 대한 실행이 된다.
이제 단순한 rest api를 하나 만들어보자.
요청 url '/hello'를 호출하면 단순한 문자열 데이터 "hello"가 출력되도록 코드를 구성할 것이다.
여기서 이제 TDD 방법론을 사용해야 하는데,
우리는 흔히 프로덕션 코드를 먼저 작성하고 이를 테스트하려고 한다.
하지만 TDD는 테스트코드를 작성하면서 프로덕션 코드가 생성되야 한다.
이와 같은 테스트코드가 먼저 작성이 되면서 컨트롤러의 코드가 작성된다고 생각하면 편하다.
우선 테스트코드를 살펴보면,
책에서는 Junit4를 기준으로 구술을 하고 있지만,
나는 최신버전인 Junit5를 기준으로 만들었다.
Junit4와의 차이점이라면 우선 사용되는 어노테이션이 다르다.
책에서 사용하는 Junit4의 경우에는
@RunWith라는 어노테이션을 정의하여 사용하도록 되어있다.
@RunWith는 Junit5에서 넘어오면서 사용하지 않게되는 어노테이션이고
이를 대체하기 위해서 @ExtendWith를 사용하게 된다.
그 외에는 일단 사용함에 있어서 아직 큰 차이점을 느끼진 못하고 있다.
테스트코드가 일단 단순한 상태이기 때문일 것이다.
@WebMvcTest 어노테이션은 웹상에서 요청과 응답에 대해 테스트로 컨트롤러를 테스트할 수 있도록 기능을 제공 해준다.
이때 스캔 대상이 되는 기준은 @Controller, @ControllerAdvice, @JsonComponent, Converter, GenericConverter, Filter, HandlerInterceptor 등이 있다.
그리고 대상적용 class파일을 명시할 수 있고 명시되지 않으면 모든 스캔 대상을 검색하기 때문에 나중에 다룰 JPA를 이용하는 부분에서 문제가 발생한다.
MockMvc는 웹 애플리케이션을 애플리케이션 서버에 배포하지 않고도 스프링 MVC의 동작을 재현할 수 있는 클래스이다.
체이닝을 지원하며 .perform에서 호출할 url을 설정하고
.andExpect에서 검증되야할 내용들을 후술하는 방식으로 코드를 작성했다.
추가적으로 .perform 안에서 요청 url과 더불어 파라메터를 같이 사용 할 수 있다.
TDD에 대한 간략한 개념을 정리하는 시간을 가져 봤다.
Mock 프래임워크는 처음 사용해봤지만 기본적인 사용방법은 생각보단 단순해서 이해하기 어렵지는 않았던 것 같다.
Lombok은 자바를 사용할때는 참 간변하게 해주는 장점은 있는 것 같지만,
나중에 Lombok을 대체하기 위한 리팩토링이 수행 되는 것에 대한 고민거리를 만들어 주기도 했다.
다음장에는 JPA를 사용하여 조회/등록/수정을 다뤄보도록 할 예정이다.