본문 바로가기

우아한테크코스/코드 리뷰

지하철 2

이번 미션에서는 본격적으로 ATDD 사이클로 미션을 구현했다.

ATDD는 (Acceptance Test Driven Development)로 인수 테스트를 작성 후 TDD로 개발을 진행하는 방식이다.

ATDD의에 관련된 내용을 간단히 정리하며 학습하자.

  1. 인수 테스트 작성
  2. Mock 서버 구현으로 인수 테스트 성공 시키기.
  3. Controller에서 비즈니스 로직은 Service로 위임
  4. Service 로직 단위 테스트 작성
  5. Service 로직 단위 테스트를 Mock 객체로 행위를 미리 지정해줌으로써 성공 시키기.
  6. Serivce 로직 구현
  7. 도메인 단위 테스트
  8. 도메인 구현

TDD의 진행 방향에 따른 방법

  1. Outside In
    • 외부에서 안쪽으로 TDD를 진행한다.
    • Contoller -> Service -> Domain
    • Mock 객체로 테스트를 성공하면 Mock 객체에 대한 명세로 다음 테스트를 시작한다.
    • 도메인에 대한 이해도가 높지 않은 상태에서 진행 가능
  2. Inside Out
    • 전통적인 방법으로 내부를 먼저 구현한 후 외부에서 참조하는 것들을 구현하는 순서로 진행한다.
    • 다른 도메인들과의 관계를 고려하지 않고 시작한다.
    • 작성이 끝나면 해당 객체와 관계를 가지는 객체를 작성

Outside In vs Inside Out

  • 컨트롤러를 먼저 만들것인지 도메인을 먼저 만들것인지는 정답은 없다.
  • 인수 테스트로 인해서 우리는 어떤 컨트롤러가 나와야 하는지 알고 있으므로 컨트롤러를 먼저 작성해도 좋고 반대로 도메인 모델의 기능 정의가 나와있는 상황에서 도메인을 먼저 작성해도 좋다.
  • 컨트롤러와 도메인의 기능을 알고 있으므로 아는것에서 모르는것으로 흐르는 방향은 두 경우 같다.

통합과 고립(Sociable and Solitary)

  • 단위 테스트 작성 시 관계를 맺고있는 대상이 있을 때 실제 객체로 사용할 것인지 Mock 객체로 사용할 것인지에 따라 나뉜다.
  • 실제 객체를 사용한다면 통합
  • 가짜(Mock) 객체를 사용한다면 고립
  • 어떤 방법을 사용해야 좋은지는 정답이 없다.
  • Mock 객체를 사용하면 당연히 속도가 빠르다. 하지만 해당 자원이 안정적이고 속도도 빠르다면 Mock 객체를 사용할 이유가 없다.
  • 개발 환경과 테스트 대상 그리고 협력 객체의 상태에 따라서 적절한 방법을 사용해야 한다.

ETag를 사용해서 캐시를 설정하는 방법도 배웠다.

컨트롤러로 설정해주는 것과 Bean으로 관리하는 방법이 있는데 Bean으로 관리하는 방법이 한 번에 적용되기 때문에 더 편하고 좋은 방법같다.

@Configuration
public class ETagHeaderFilter {
    @Bean
    public FilterRegistrationBean<ShallowEtagHeaderFilter> shallowEtagHeaderFilter() {
        FilterRegistrationBean<ShallowEtagHeaderFilter> filterRegistrationBean = new FilterRegistrationBean<>(new ShallowEtagHeaderFilter());
        filterRegistrationBean.addUrlPatterns("/foos/*");
        filterRegistrationBean.setName("etagFilter");
        return filterRegistrationBean;
    }
}

이런식으로 적용해주면 된다.

@Bean은 @Configuration으로 선언된 클래스 내에 있는 메소드를 정의할 때 사용한다. 이 메소드가 반환하는 객체가 bean이 되며 default로 메소드 이름이 bean의 이름이 된다.


이번 주차에서는 외부 라이브러리인 jgrapht를 사용해서 지하철 역간의 최단 거리 경로, 최소 시간 경로를 조회하는 미션을 진행했다.

리뷰받은 내용을 정리해보자.


외부 라이브러리 테스트 같은 경우에는 구현을 수정할 수 없기 때문에 단위 테스트를 하지 않지만 라이브러리의 기능을 알아보기 위한 학습테스트를 작성했었다.

외부 라이브러리 테스트는 다른 클래스로 분리하여 테스트해야 한다는 것을 배울 수 있었다. 직접 만든 코드가 아님을 분리하기 위함과 다른 라이브러리로 바꿔낄 가능성이 있기 때문인 것 같다.


래밸1 때 배웠던 @ParameterizedTest의 @CsvSource, @MethodSource를 사용한 테스트 방식을 까먹고 있었다. 한동안 안쓰고 있으면 역시 까먹는 것 같다. 주기적으로 복습하며 응용하는 습관을 가지자..


createdAt이나 updatedAt 같은 변수들은 DB에 저장될 때만 변경되기 때문에 엔터티 생성, 수정 시 자동으로 할당, 변경되게 짜는 게 좋다는 것을 배웠다.

@EnableJdbcAuditing 이라는 Spring Data Jdbc의 에노테이션을 알게되었다.

@CreatedDate와 @LastModifiedDate를 사용하면 DB에 저장, 수정될 때 자동으로 변경되기 때문에 코드에서 관련 내용이 빠지고 한결 깔끔해짐을 느꼈다. JPA에서도 관련 기능이 있는 것 같고 앞으로 쓸 일이 많을 것 같다. 잘 기억해둬야지.


외부 라이브러리는 오히려 변경될 일이 없다고 생각했었는데 아니였다. 오히려 비슷한 라이브러리들이 많기 때문에 상황에 따라 다른 라이브러리들로 바뀔 가능성이 높다.

외부 라이브러리는 변경될 가능성이 높다는 것을 인지하고 항상 고립시켜서 결합도를 낮춰야겠다.


SpringBoot 사용법에 점점 익숙해지고 있는 것 같다.

또 MockMvc, RestAssured 등등 다양한 테스트에 대해 알게되어서 더 안전한 프로그램을 만들 수 있을 것 같다. 여러번 사용해보고 응용해보며 내 것으로 만들어야겠다.

'우아한테크코스 > 코드 리뷰' 카테고리의 다른 글

점진적인 리팩토링  (0) 2020.12.23
지하철 3  (0) 2020.05.23
지하철 1  (0) 2020.05.10
체스 게임 3  (0) 2020.05.05
체스 게임 2  (0) 2020.04.25