본문 바로가기
개발/Junit

⑤Service Junit 테스트 - 3 등록과 리스트 junit테스트

by 외노자개발 2022. 10. 19.
반응형

Junit 초기 설정 

//@DataJpaTest //Tranjectional あるため、テスト後ロールバックします。
@ExtendWith(MockitoExtension.class)
public class BookServiceTest {
	
	@InjectMocks
	private BookService bookService;
	@Mock
	private BookRepository bookRepository;
	@Mock
	private MailSender mailSender;

//	@Autowired
//	private BookRepository bookRepository;
	
	// 気になる… サービスだけテストしたいけど、レポジトリもテストになる Mockito使用

@ExtendWith(MockitoExtension.class) : Mockito와 Junit5를 같이 사용하기 위해서 사용한다. 

 

@InjectMock은 DI를 @Mock이나 @Spy로 생성된 mock 객체를 자동으로 주입해주는 어노테이션입니다.

 

@Mock으로 만든 mock 객체는 가짜 객체이며 그 안에 메소드 호출해서 사용하려면 반드시 스터빙(stubbing)을 해야합니다. 

 

해석해보자면, BookService를 Test하기 위해 Mokito를 이용한다. (가짜 객체를 생성)

@InjectMocks를 이용해서 실제 BookService를 DI해주고,,

@Mock을 이용해서 가짜로 된 DB인 BookRepository와 메일을 보내기 위한 클래스 MailSender를 가짜 객체로 만든다. 

이것은 추후에 stub이란 스터빙을 해줘야 하는데 이것은 아래에서 다루겠다. 

 

 


1.Book 등록 테스트

	@Test
	public void bookSaveTest() {
		//given
		BookSaveReqDto dto = new BookSaveReqDto();
		dto.setTitle("junit-seo");
		dto.setAuthor("meta-seo");
		
		//stub(行動定義)
		when(bookRepository.save(any())).thenReturn(dto.toEntity());
		when(mailSender.send()).thenReturn(true);
		
		//when
		BookRespDto bookRespDto = bookService.bookSave(dto);
		
		//then
//		assertEquals(dto.getTitle(), bookRespDto.getTitle());
//		assertEquals(dto.getAuthor(), bookRespDto.getAuthor());
		assertThat(bookRespDto.getTitle()).isEqualTo(dto.getTitle());
		assertThat(bookRespDto.getAuthor()).isEqualTo(dto.getAuthor());
		
	}

이제는 실제로  Service쪽을 테스트를 해보겠다. 

추가로 stub이란 항목이 생겼다. 

stub이란,, 테스트 용도로 하드 코딩한 값을 반환하는 구현체를 의미한다...

databse와 connect 하거나 web service를 call 할 수 있는지에대해 test하고 싶은 것이 아닙니다. 따라서, 이와 같은 부분들은 하드코딩으로 대체하고, 우리가 test 하고자하는 business logic에 집중하고자 Stub을 사용한다. 

 

 

해석해보자면,

given// BookSaveReqDto dto를 만들고, dto에 값을 임의로 넣어준다. 

stub// 에서는 반환을 위해 when을 사용. thenReturn의 리턴값으로 방금 임의로 넣어준 dto를 toEntity로 객체로 만들어 준다. 그 후  bookRepository의 save메서드를 이용해서 값을 저장. 

when// 에서는 BookRespDto 에 방금 dto로 세이브한 값을 넣어준다. 

 

Request -> BookSaveReqDto  -> toEntity()를 이용 Book객체로 builder한다.-> BookRespDto에 저장->Response

 

마지막으로 assertThat // bookRespDto에 저장한 값과 SaveReqDto에 들어온 값을 비교해준다. 

 

 

 2. Book리스트 테스트

 

    @Test
	public void bookListTest() {
		//given(パラメータから入るデータ)
		
		//stub(仮説)
		List<Book> books = new ArrayList<>();
		books.add(new Book(1L, "junit-seo", "meta-seo"));
		books.add(new Book(2L, "spring-seo", "coding-seo"));
		when(bookRepository.findAll()).thenReturn(books);
		
		//when(実行)
		List<BookRespDto> bookRespDtoList = bookService.bookList();
		
		//print
		bookRespDtoList.stream().forEach((dto)-> {
			System.out.println(dto.getId());
			System.out.println(dto.getTitle());
			System.out.println(dto.getAuthor());
			System.out.println("2.-------------------------------------------------------------------------");
		});
		
		//then(検証)
		assertThat(bookRespDtoList.get(0).getTitle()).isEqualTo("junit-seo");
		assertThat(bookRespDtoList.get(0).getAuthor()).isEqualTo("meta-seo");
		assertThat(bookRespDtoList.get(1).getTitle()).isEqualTo("spring-seo");
		assertThat(bookRespDtoList.get(1).getAuthor()).isEqualTo("coding-seo");
		
	}

List는 검색이기에 given을 따로 받을 필요 없다.

stub에서 List<Book> books = new ArrayList<>(); 를 사용하는 이유를 알아보자...

ArrayList는 구현체가 아닌 List인터페이스로 작성된다. 

ArrayList를 업캐스팅 하는 이유는 유연성을 위한 것이다. 

ArrayList<>()의 빠른 탐색과 검색을 이용하면서  List의 장점인 유연성을 이용한 것이다.

 

stub// List<Book> books = new Array<>();를 이용해서 리스트에 books를 담는다. 

books.add는 List형태의 삽입 메서드 이며 new해서 객체를 넣은 이유는 

리스트로써 안에 객체들이 들어있는 경우를 생각하여, 리스트 안에 각 객체를 추가한 것이다. 

when 으로 bookRepository.findAll() 로 지금까지 등록한 books를 가져온다. 

when// List로 된BookRespDto를 만들어 bookService의 bookList메서드를 실행시켜 방금stub에서 설정한 값을 가져온다.

print// 값을 눈으로 확인하기 위해 쓴 코드 이다.  List이기 때문에 stream의 foreach을 이용해서 sysout을 구현했다. 

해석 해보자.. bookRespDtoList는 방금 만든 List이다. 그것을  stream으로 하고 foreach로 dto로 변수를 만들어 안에 있는 값들을 프린트 한다. 

 

then// assertThat을 이용해서  List의 get(0)번째와 isEqualTo("값") 을 비교해준다. 

 

북 수정과 검색은 다음 게시물에서 진행하도록 하겠다. 

 

반응형

댓글