본 시리즈는 메타 코딩님의 Junit 강의를 학습한 내용을 바탕으로 정리하였습니다.
서비스 레이어를 테스트하는 과정 중에 있다. 이번에는 책 목록보기를 테스트 할 차례이다.
BookServiceTest.java
package site.metacoding.junitproject.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.assertj.core.util.Arrays;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import site.metacoding.junitproject.domain.Book;
import site.metacoding.junitproject.domain.BookRepository;
import site.metacoding.junitproject.util.MailSender;
import site.metacoding.junitproject.util.MailSenderStub;
import site.metacoding.junitproject.web.dto.BookRespDto;
import site.metacoding.junitproject.web.dto.BookSaveReqDto;
@ExtendWith(MockitoExtension.class) // 가짜 메모리 환경 만들기
public class BookServiceTest {
@InjectMocks
private BookService bookService;
@Mock
private BookRepository bookRepository;
@Mock
private MailSender mailSender;
@Test
public void 책등록하기_테스트() {
// (..생략)
}
@Test
public void 책목록보기_테스트() {
// given(파라미터로 들어올 데이터)
// stub (가설)
List<Book> books = new ArrayList<>();
books.add(new Book(1L, "junit강의", "메타코딩"));
books.add(new Book(2L, "스프링강의", "겟인데어"));
when(bookRepository.findAll()).thenReturn(books);
// when (실행)
List<BookRespDto> dtos = bookService.책목록보기();
// then (검증)
assertThat(dtos.get(0).getTitle()).isEqualTo("junit강의");
}
}
우리는 Stub
을 사용하기로 했으니 가설을 잘 세우는게 중요할 것이다. 여기서도 "책 등록하기 테스트" 와 마찬가지로 books
객체를 List로 생성하고 books
에 추가하는 내용들이 bookRepository
에서 return
되는 값들이다 (즉, books
객체에 추가하는 내용은 bookRepository
에 저장되는 값이다) 라는 가설과 함께 그에 맞는 검증을 실행한다.
그렇다면, 이제 테스트를 실행해보자.
과연 그 결과는...?
(요즘 자주 뜨는 것 같은...)
로그를 읽어보니 Array의 0
번째 인덱스에 "junit 강의" 가 들어와야하는데 1
번째 인덱스인 "스프링 강의" 가 들어왔다고 뜬다.
뭔가 이상하다. 일단 dto
에 어떤 값들이 뜨는지 다음의 출력문을 추가해서 확인해보자.
// print
dtos.stream().forEach((dto) -> {
System.out.println(dto.getId());
System.out.println(dto.getTitle());
System.out.println("=================");
});
테스트를 다시 실행하고 콘솔창에 출력된 값을 보면....
Id 2
번 값만 들어오고 1
번이 들어오지 않는다. 그렇다면 이는 테스트 코드 문제가 아니라 원래의 본 코드의 문제인 것 같다. BookService
의 책 목록보기 파트를 다시 한번 보자.
BookService.java
// 2. 책 목록보기
public List<BookRespDto> 책목록보기() {
return bookRepository.findAll().stream()
.map(new BookRespDto()::toDto)
.collect(Collectors.toList());
}
이 또한 테스트 코드에서 출력문을 작성한 것처럼 출력문을 통해 정말 본 코드의 문제가 맞는지 확인해보자.
다음과 같이 작성한다.
// 2. 책 목록보기
public List<BookRespDto> 책목록보기() {
// 코드 수정
List<BookRespDto> dtos = bookRepository.findAll().stream()
.map(new BookRespDto()::toDto)
.collect(Collectors.toList());
// print
dtos.stream().forEach((dto) -> {
System.out.println("================= 본코드");
System.out.println(dto.getId());
System.out.println(dto.getTitle());
});
return dtos;
}
언능 실행해보자.
본 코드도 똑같이 나온다. 역시 추측대로 원래 코드에서 뭔가가 작동이 되지 않는 것이 맞았다.
아마도 .map(new BookRespDto()::toDto)
이 부분에서 문제가 생긴 것 같다. 오류를 해결해보자.
BookService
를 다음과 같이 수정한다.
BookService.java
// 2. 책 목록보기
public List<BookRespDto> 책목록보기() {
// 코드 수정
List<BookRespDto> dtos = bookRepository.findAll().stream()
.map((bookPS) -> new BookRespDto().toDto(bookPS))
.collect(Collectors.toList());
// print
dtos.stream().forEach((dto) -> {
System.out.println("================= 본코드");
System.out.println(dto.getId());
System.out.println(dto.getTitle());
});
return dtos;
}
BookServiceTest.java
@Test
public void 책목록보기_테스트() {
// given(파라미터로 들어올 데이터)
// stub (가설)
List<Book> books = new ArrayList<>();
books.add(new Book(1L, "junit강의", "메타코딩"));
books.add(new Book(2L, "spring강의", "겟인데어"));
when(bookRepository.findAll()).thenReturn(books);
// when (실행)
List<BookRespDto> bookRespDtoList = bookService.책목록보기();
// print
bookRespDtoList.stream().forEach((dto) -> {
System.out.println("================= 테스트");
System.out.println(dto.getId());
System.out.println(dto.getTitle());
});
// then (검증)
assertThat(bookRespDtoList.get(0).getTitle()).isEqualTo("junit강의");
assertThat(bookRespDtoList.get(0).getAuthor()).isEqualTo("메타코딩");
assertThat(bookRespDtoList.get(1).getTitle()).isEqualTo("spring강의");
assertThat(bookRespDtoList.get(1).getAuthor()).isEqualTo("겟인데어");
}
위와 같이 검증도 추가하고 dtos도 bookRespDtoList로 바꿨다. 이제 테스트를 실행하면
통과가 뜬다!