워밍업 클럽 4기 백엔드 - Day 16 미션
Practical Testing: 실용적인 테스트 가이드
Layered Architecture 구조의 레이어별 테스트 작성법을 알아보았습니다. 레이어별로 1) 어떤 특징이 있고, 2) 어떻게 테스트를 하면 좋을지, 자기만의 언어로 다시 한번 정리해 볼까요?
Persistence Layer
특징
'영속성'이라는 이름처럼 영속성을 지니는 데이터에 접근하기 위한 계층
컴퓨터에서 영속성을 지니는 데이터란 곧 보조기억장치에 저장되는 파일을 의미
데이터에 접근한다는 말은 곧 데이터를 읽거나 쓰는 작업을 의미
결과적으로 영속성 계층에 대한 테스트는, 의도한대로 데이터를 잘 읽고 쓰는지를 확인하기 위한 목적의 테스트
일반적으로 JPA 등의 기술을 이용해 Persistence Layer를 구성하며, Persistence Layer가 비즈니스 로직을 포함하지 않도록 주의
테스트 방법
@DataJpaTest또는@SpringBootTest를 이용해 Bean을 생성하고, 테스트 하고자 하는 Repository의 Bean을 주입 받아 테스트를 진행한다.데이터 읽기, 쓰기 작업이 잘 이루어지는지 검증하는 비교적 단순한 테스트가 이루어져 약간 단위 테스트 같은 느낌
@DataJpaTest를 쓰면 Repository 관련 Bean만 생성해서 서버를 띄우기 때문에 상대적으로 가볍고,@Transactional이 적용되어 있어 테스트 메소드 실행 후 자동으로 Rollback 된다.
Business Layer
특징
서비스의 가장 핵심이 되는 계층으로, 비즈니스 로직을 포함하는 계층
비즈니스 로직과 도메인 규칙은 모두 비즈니스 계층에 위치하는 것이 원칙
비즈니스 로직을 처리하기 위해서는 데이터가 필요하므로, 자연스럽게 Persistence Layer에 의존한다.
비즈니스 계층이 영속성 계층에 의존하는 것은 자연스러운 일이지만, JPA 기술을 사용하는 경우에는 결합도가 너무 강해지는 측면이 있으며 결합도 문제를 해결하기 위한 구조로 헥사고날 아키텍처가 고안되기도 했다.
하나의 비즈니스 로직을 수행하기 위해 데이터에 여러번 접근해야 할 수 있으나, 데이터에 대한 접근은 원자성을 전제로 한다.
즉, 하나의 비즈니스 로직에서 호출하는 Persistence Layer의 서비스들은 하나의 트랜잭션으로 묶는 것이 일반적이다.
테스트 방법
일반적으로 비즈니스 계층의 메소드는 하위 레이어인 영속성 계층의 서비스에 의존하므로
@SpringBootTest를 이용한 통합 테스트로 진행한다.Repository에 비즈니스 로직을 처리하기 위한 데이터를 저장하고, 이를 기반으로 비즈니스 로직의 동작을 검증한다.
Layered Architecture에서 정말 단순한 CRUD만 수행하는 서비스 메소드에 대한 테스트는 사실상 Repository 테스트와 크게 다르지 않을 수 있다. 그러나 비즈니스 로직은 얼마든 확장 또는 변경이 가능하므로 별도로 테스트를 작성해주는 것이 좋다.
비즈니스 계층의 테스트 시에는
@Transactional설정을 통해 트랜잭션의 범위를 명확히 설정해야 한다.
Presentation Layer
특징
외부 세계와의 접점이 되는 계층 -> 인터페이스 cf. API
외부의 요청을 받고, 비즈니스 계층의 서비스를 이용해 응답을 반환 -> 비즈니스 계층에 의존적
Presentation Layer의 주요 책임은 요청 수신 & 응답 반환
테스트 방법
요청을 받고 응답을 보내기 위한 계층이므로 테스트를 통해 요청 수신과 응답 반환이 정상적으로 이루어지는지를 검증한다.
조금 더 자세히 풀어 설명하면, 유효한 입력 데이터가 넘어오는 경우와 그렇지 않은 경우에 각각 의도한대로 올바르게 동작하는지를 응답 데이터를 통해 검증해야 한다.
Presentation Layer는 Business Layer와 Persistence Layer에 의존하지만, 비즈니스 계층과 달리 하위 계층의 서비스를 직접 이용하지 않고 Mock 객체를 사용해 테스트를 진행한다.
@WebMvcTest(controllers = XxxController.class)를 이용해 직접 지정한 Bean만 로드해 테스트할 수 있다.등록한 Presentation Layer Bean은 내부적으로 Business Layer 객체에 의존하므로, Mock 객체를 생성해 대신 주입해주어야 한다.
@MockitoBean을 사용해 Mock 객체를 생성해 주입해줄 수 있다.
댓글을 작성해보세요.