Programming/TDD Project
Pull Request 010 - 자유게시글 조회 기능 TDD로 구현해보기
JKROH
2023. 11. 10. 15:20
반응형
이번에는 게시글 조회 기능이다. 앞서 작성과 수정 기능을 마치고 삭제 기능을 먼저 조회하려 했으나, 수정 기능에서부터 겹쳤던 조회 기능을 모른척 할 수가 없었다.
조회 기능의 로직은 다음과 같다.
- FreeBoardService#getFreeBoard(long id) 를 통해 조회 명령을 받는다.
- FreeBoardQueryService#readEntityById(long id) 메서드를 통해 레포지토리에 FreeBoard 엔티티 조회 쿼리를 날린다.
- 조회한 엔티티 쿼리를 Response DTO로 바꿔 반환한다.
우선 2번에 대한 테스트를 진행해볼 것이다. 먼저 테스트를 진행할 클래스를 생성하고 필요한 필드들을 채우고, 테스트 메서드를 만들었다.
class FreeBoardQueryServiceTest {
@Mock
private FreeBoardRepository freeBoardRepository;
@InjectMocks
private FreeBoardQueryService freeBoardQueryService;
@Test
void testReadEntityById() {
}
}
FreeBoardQueryService#readEntityById()의 핵심은 id 값으로 적절한 값이 들어오면 엔티티를 반환하지만, 부적절한 값이 들어오면 예외를 던져야한다는 것이다. 따라서 우리는 두 가지를 테스트해야 한다.
- 적절한 id가 인자로 넘어가면 엔티티를 반환한다.
- 부적절한 id가 인자로 넘어가면 예외를 던진다.
이제 테스트 메서드를 채워보자. 먼저 적절한 id값과 부적절한 id값 그리고 적절한 id값을 제공했을 때 반환받을 객체가 필요할 것이다.
@Test
void testReadEntityById() {
// given
long appropriateId = 1L;
long inappropriateId = 0L;
Optional<FreeBoard> testEntity = Optional.of(FreeBoard.builder()
.title("title")
.content("content")
.build());
}
이제 MockRespoisotry에서 반환할 값을 처리해주자.
@Test
void testReadEntityById() {
// given
long appropriateId = 1L;
long inappropriateId = 0L;
Optional<FreeBoard> testEntity = Optional.of(FreeBoard.builder()
.title("title")
.content("content")
.build());
//when
given(freeBoardRepository.findById(appropriateId)).willReturn(testEntity);
given(freeBoardRepository.findById(inappropriateId)).willReturn(Optional.empty());
FreeBoard foundEntity = freeBoardQueryService.readEntityById(appropriateId);
}
이제 마지막 단계다. 다시 한 번 테스트 해볼 두 가지를 가지고 상태값을 상정하자.
- 적절한 id값으로 찾아온 foundEntity와 Optional객체인 testEntity에서 뽑아온 객체는 같아야한다.
- 부적절한 id값으로 FreeBoardQueryService#readEntityByID()를 실행하면 예외를 던진다.
- 이번에는 테스트 작성을 위해 RuntimeException으로 예외를 설정했지만, 추후 예외 클래스를 제작할 예정이다.
@Test
void testReadEntityById() {
// given
long appropriateId = 1L;
long inappropriateId = 0L;
Optional<FreeBoard> testEntity = Optional.of(FreeBoard.builder()
.title("title")
.content("content")
.build());
//when
given(freeBoardRepository.findById(appropriateId)).willReturn(testEntity);
given(freeBoardRepository.findById(inappropriateId)).willReturn(Optional.empty());
FreeBoard foundEntity = freeBoardQueryService.readEntityById(appropriateId);
//then
assertThat(foundEntity).isEqualTo(testEntity.get());
assertThrows(RuntimeException.class, ()->freeBoardQueryService.readEntityById(inappropriateId));
}
then절의 실행 값들을 통해 테스트를 마무리 할 수 있을 것이다. 이를 기반으로 readEntityById()를 구현하자.
@Service
public class FreeBoardQueryService {
private final FreeBoardRepository freeBoardRepository;
public FreeBoardQueryService(FreeBoardRepository freeBoardRepository) {
this.freeBoardRepository = freeBoardRepository;
}
@Transactional(readOnly = true)
public FreeBoard readEntityById(long id) {
return freeBoardRepository.findById(id).orElseThrow(() ->
new RuntimeException());
}
}
테스트가 잘 수행됨을 확인할 수 있다. 앞선 단계에서 테스트 메서드를 작성해보았기 때문에 테스트 메서드를 처음부터 한 단계씩 작성하는 과정을 모두 적지는 않았다.
전체 코드는 링크에서 확인할 수 있다.
반응형