본 시리즈는 메타 코딩님의 Junit 강의를 학습한 내용을 바탕으로 정리하였습니다.
서비스 레이어의 책 한건보기와 삭제, 수정 테스트는 쉽고 단순한 관계로 한 번에 진행하도록 했다. 내용 또한 겹치는 부분이 많다.
BookServiceTest.java
@Test
public void 책한건보기_테스트() {
// given
Long id = 1L; // 1.
// stub
Book book = new Book(1L, "junit강의", "메타코딩");
Optional<Book> bookOP = Optional.of(book);
when(bookRepository.findById(id)).thenReturn(bookOP);
// 2.
// when
BookRespDto bookRespDto = bookService.책한건보기(id);
// 3.
// then
assertThat(bookRespDto.getTitle()).isEqualTo(book.getTitle());
assertThat(bookRespDto.getAuthor()).isEqualTo(book.getAuthor());
// 4.
}
<코드 설명>
new
로 해서 객체를 생성한다.bookRepository
는 가짜로 만들었다. 따라서 bookRepository.findById(id)
을 stub으로 처리한다. 그리고 findById
는 optional을 리턴하기 때문에 Book을 optional로 감쌌다.bookOP
에는 1L
, "junit강의"
, "메타코딩"
이 들어와있을 것이다. 우리는 이것을 bookRespDto
로 받을 것이다.bookRespDto
의 Title과 Author의 내용을 assertThat
로 검증한다.실제로 테스트를 돌려보자.
성공. 이제는 초록불이 뜨면 마음이 편해진다.
다음은 책 삭제와 책 수정 테스트이다. 그런데 책 삭제의 경우는 정말 삭제하는 것 말고는 기능이 없기 때문에 강사님께서 테스트를 생략하셨다. 나도 따라서 과감히 생략했다.
BookServiceTest.java
@Test
public void 책수정하기_테스트() {
// given
Long id = 1L;
BookSaveReqDto dto = new BookSaveReqDto();
dto.setTitle("spring강의"); // spring 강의
dto.setAuthor("겟인데어"); // 겟인데어
// 1.
// stub
Book book = new Book(1L, "junit강의", "메타코딩");
Optional<Book> bookOP = Optional.of(book);
when(bookRepository.findById(id)).thenReturn(bookOP);
// 2.
// when
// then
}
<코드 설명>
id
와 BookSaveReqDto
를 가지고 있다. 이는 수정 테스트를 위한 것으로 dto
의 Title과 Author 를 각각 "spring강의", "겟인데어" 로 변경하여 준비해놓는다.stub
의 내용은 bookRepository
에서 찾고 더티체킹을 하는 방식이기 때문에 위의 "책 한건보기" 테스트와 똑같은 내용이다. 따라서 그대로 복사한다.그런데 한 가지 의문점이 있다.
우리가 이렇게 테스트를 구현했지만 실제로 테스트가 잘 작동했는지 알 수 있는 방법이 없다.
BookService.java
// 5. 책 수정하기
@Transactional(rollbackOn = RuntimeException.class)
public void 책수정하기(Long id, BookSaveReqDto dto) { // id, title, author
Optional<Book> bookOP = bookRepository.findById(id); // 1, 2, 3
if(bookOP.isPresent()) {
Book bookPS = bookOP.get();
bookPS.update(dto.getTitle(), dto.getAuthor());
}else {
throw new RuntimeException("해당 아이디를 찾을 수 없습니다.");
}
} // 메서드 종료시에 더티체킹으로 update됨.
즉, 위처럼 BookService.java
에서 실제로 업데이트가 잘 실행되었는지 return 값이 없기 때문에 책 수정하기 메서드를 테스트해 볼 수가 없는 것이다.
다시 코드를 손봐야 한다.
BookService.java
// 5. 책 수정하기
@Transactional(rollbackOn = RuntimeException.class)
public BookRespDto 책수정하기(Long id, BookSaveReqDto dto) { // id, title, author
Optional<Book> bookOP = bookRepository.findById(id);
if(bookOP.isPresent()) {
Book bookPS = bookOP.get();
bookPS.update(dto.getTitle(), dto.getAuthor());
return bookPS.toDto();
}else {
throw new RuntimeException("해당 아이디를 찾을 수 없습니다.");
}
}
변경 :
void
->BookRespDto
추가 :return bookPS.toDto();
위의 코드 수정으로 책 수정하기를 진행했을 때, Dto
를 통해 업데이트가 정상적으로 완료되었는지를 확인해볼 수 있게 되었다. 이제 책 수정하기 메소드의 when
과 then
을 마무리해보자.
BookServiceTest.java
@Test
public void 책수정하기_테스트() {
// given
Long id = 1L;
BookSaveReqDto dto = new BookSaveReqDto();
dto.setTitle("spring강의"); // spring 강의
dto.setAuthor("겟인데어"); // 겟인데어
// stub
Book book = new Book(1L, "junit강의", "메타코딩");
Optional<Book> bookOP = Optional.of(book);
when(bookRepository.findById(id)).thenReturn(bookOP);
// when
BookRespDto bookRespDto = bookService.책수정하기(id, dto);
// then
assertThat(bookRespDto.getTitle()).isEqualTo(dto.getTitle());
assertThat(bookRespDto.getAuthor()).isEqualTo(dto.getAuthor());
}
완성된 "책 수정하기" 테스트 코드이다.
책 수정하기 테스트 메소드를 통해 원래의 "junit강의"
, "메타코딩"
을 given
의 "spring강의"
, "겟인데어"
로 update를 진행하였고 (when
에서 bookRespDto
가 변경되면서 더티체킹됨)하였고, 이를 then
에서 검증하게 되면서 책이 수정 되었는지 테스트를 할 수 있게 되었다.