Service - 책 목록보기 테스트

jihan kong·2022년 9월 20일
0

JUnit5

목록 보기
17/25
post-thumbnail

본 시리즈는 메타 코딩님의 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에 저장되는 값이다) 라는 가설과 함께 그에 맞는 검증을 실행한다.


그렇다면, 이제 테스트를 실행해보자.

과연 그 결과는...?


Test fail ⚠️

(요즘 자주 뜨는 것 같은...)

로그를 읽어보니 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로 바꿨다. 이제 테스트를 실행하면

통과가 뜬다!

profile
학습하며 도전하는 것을 즐기는 개발자

0개의 댓글