Junit - 18강

연어는결국강으로·2022년 10월 5일
0

Junit

목록 보기
7/9

2022.10.05 수강

18강. 서비스레이어 메일보내기 가짜 기능 구현

1. 목표

만일 구현하고자 하는 기능이 책 등록을 하면 이메일을 보내는 기능이고 이메일을 보내는 것은 내가 구현하는 부분이 아니라면 그림처럼 MailSender를 이용하여 테스트할 수 있다.


2. 필요한 클래스 생성

  • Mail 클래스 생성

    • 아직 구현이 된게 아니다!! 즉 내가 작업할때는 없다는 뜻임
    public class Mail {
        public boolean sendMail() {
            //기능
            return true;
        }
    }
  • MailSender 인터페이스 생성

    public interface MailSender {
        boolean send();
    }
  • MailSenderStub 클래스 생성

    import org.springframework.stereotype.Component;
    
    @Component
    public class MailSenderStub implements MailSender {
    
        @Override
        public boolean send() {
            // TODO Auto-generated method stub
            return false;
        }
    
    }
    • Stub은 가정이라는 뜻이다. 즉 가짜이다.
    • @Component 를 쓰면 IoC 컨테이너에 등록된다.
  • MailSenderAdapter 클래스 생성

    public class MailSenderAdapter implements MailSender {
    
        //private Mail mail;
    
        //public MailSenderAdapter() {
        //    this.mail = new Mail();
        //}
    
        @Override
        public boolean send() {
            return true;
        }
    }
  • BookService에 코드 추가

    @Service
    @RequiredArgsConstructor
    public class BookService {
        private final BookRepository bookRepository;
        // 추가하는 부분
        private final MailSender mailSender;
    
        // 1. 책등록
        @Transactional(rollbackFor = RuntimeException.class)
        public BookRespDto 책등록하기(BookSaveReqDto dto) {
            Book bookPS = bookRepository.save(dto.toEntity());
            
            // if절 추가하면됨!!
            if(bookPS != null) {
                if(!mailSender.send()) {
                    throw new RuntimeException("메일이 전송되지 않았습니다.");
                }
            }
            return new BookRespDto().toDto(bookPS);
        }

3. 메일 기능이 구현이 되었다면
MailSenderAdapter에 @Component 어노테이션을 달고 Stub에 있는 @Component를 지워야한다. 두 개를 쓰면 안되는 이유는 스프링은 IoC 컨테이너를 싱클톤으로 관리하기 때문에 같은 타입을 올릴 수 없어서이다.


19강. 서비스레이어 테스트 - 실제 DB 테스트하기

  BookServiceTest에 BookService를 메모리에 띄워야 되는데 BookService는 BookRepository와 MailSender에 의존하고 있다.
 MailSender는 Stub를 사용하면 쉽게 해결할 수 있다.
 그럼 BookRepository는? 이것 역시 Respository를 테스트할 때 했던 것처럼 위에 @DataJpaTest를 붙이고 DI해서 사용하면 되는 것이 아닌가? 하는 생각에 한번 해보았다.

	@Test
	public void 책등록하기_테스트() {
		// given
		BookSaveReqDto dto = new BookSaveReqDto();
		dto.setTitle("junit lecture");
		dto.setAuthor("momo");
		
		// stub
		MailSenderStub mailSenderStub = new MailSenderStub();
		
		// when
		BookService bookService = new BookService(bookRepository, mailSenderStub);
		BookRespDto bookRespDto =  bookService.책등록하기(dto);
		
		// then
		assertEquals(dto.getTitle(), bookRespDto.getTitle());
		assertEquals(dto.getAuthor(), bookRespDto.getAuthor());
	}

이렇게 해보니 잘 된다. 그럼 이대로 괜찮은가? 아니다. 이대로 하면 Service만 테스트하고 싶은데 repository 레이어가 함께 테스트 된다. 이건 어떻게 해결해야 하는가. 이것도 mailStub처럼 가짜 repository를 만들어서 해결할 수 있다. 이것을 하려면 Mockito 라는 가짜 객체를 보관하는 환경이 필요하다.

0개의 댓글