스터디/Spring
[Spring Boot] Service 단위 테스트 (4/5)
menuhwang
2022. 9. 8. 17:47
Service 단위 테스트
테스트 코드
class BoardServiceTest {
private BoardRepository boardRepository = Mockito.mock(BoardRepository.class);
private BoardService boardService = new BoardServiceImpl(boardRepository);
private final Long ID = 1L;
private final String AUTHOR = "user";
private final String TITLE = "Hi";
private final String DESCRIPTION = "Nice to meet you";
private final LocalDateTime CREATED_TIMESTAMP = LocalDateTime.now();
private final int LIKE_0 = 0;
private final int LIKE_1 = 1;
@Test
public void getBoardByIdTest() {
Board givenBoard = Board.builder()
.id(ID)
.author(AUTHOR)
.title(TITLE)
.description(DESCRIPTION)
.created_timestamp(CREATED_TIMESTAMP)
.build();
Mockito.when(boardRepository.findById(ID)).thenReturn(Optional.of(givenBoard));
BoardResDTO boardResDTO = boardService.getBoard(ID);
assertEquals(ID, boardResDTO.getId());
assertEquals(AUTHOR, boardResDTO.getAuthor());
assertEquals(TITLE, boardResDTO.getTitle());
assertEquals(DESCRIPTION, boardResDTO.getDescription());
assertEquals(LIKE_0, boardResDTO.getThumb());
assertEquals(CREATED_TIMESTAMP, boardResDTO.getCreated_timestamp());
}
@Test
public void createBoardTest() {
CreateBoardDTO givenCreateBoardDTO = CreateBoardDTO.builder()
.author(AUTHOR)
.title(TITLE)
.description(DESCRIPTION)
.build();
Board givenBoard = Board.builder()
.id(ID)
.author(givenCreateBoardDTO.getAuthor())
.title(givenCreateBoardDTO.getTitle())
.description(givenCreateBoardDTO.getDescription())
.created_timestamp(CREATED_TIMESTAMP)
.build();
Mockito.when(boardRepository.save(any(Board.class))).thenReturn(givenBoard);
BoardResDTO boardResDTO = boardService.createBoard(givenCreateBoardDTO);
assertEquals(ID, boardResDTO.getId());
assertEquals(AUTHOR, boardResDTO.getAuthor());
assertEquals(TITLE, boardResDTO.getTitle());
assertEquals(DESCRIPTION, boardResDTO.getDescription());
assertEquals(LIKE_0, boardResDTO.getThumb());
assertEquals(CREATED_TIMESTAMP, boardResDTO.getCreated_timestamp());
}
@Test
public void updateBoardTest() { // title, description 둘 중 하나만 변경할 경우 테스트는 생략
final String UPDATE_TITLE = "Hello";
final String UPDATE_DESCRIPTION = "Hello, Everyone";
UpdateBoardDTO givenUpdateBoardDTO = UpdateBoardDTO.builder()
.title(UPDATE_TITLE)
.description(UPDATE_DESCRIPTION)
.build();
Board givenBoard = Board.builder()
.id(ID)
.author(AUTHOR)
.title(TITLE)
.description(DESCRIPTION)
.created_timestamp(CREATED_TIMESTAMP)
.build();
Mockito.when(boardRepository.findById(ID)).thenReturn(Optional.of(givenBoard));
BoardResDTO boardResDTO = boardService.updateBoard(ID, givenUpdateBoardDTO);
assertEquals(ID, boardResDTO.getId());
assertEquals(AUTHOR, boardResDTO.getAuthor());
assertEquals(UPDATE_TITLE, boardResDTO.getTitle());
assertEquals(UPDATE_DESCRIPTION, boardResDTO.getDescription());
assertEquals(LIKE_0, boardResDTO.getThumb());
assertEquals(CREATED_TIMESTAMP, boardResDTO.getCreated_timestamp());
}
// 생략...
}
Mocking
Service는 Repository를 DI 받는다. 하지만 단위 테스트에서 외부 요인, 요소들은 정상작동한다는 가정하에 진행한다. 이때 외부 요소인 Repository를 mock 객체로 주입해줘야한다. 이것을 'mocking 한다' 라고 표현한다.
Mock 객체 생성
private BoardRepository boardRepository = Mockito.mock(BoardRepository.class);
Mock 객체 주입
private BoardService boardService = new BoardServiceImpl(boardRepository);
Mock 객체 메서드
Mockito.when(boardRepository.findById(ID)).thenReturn(Optional.of(givenBoard));
Mockito.when(boardRepository.save(any(Board.class))).thenReturn(givenBoard);
Mockito.when(mockMethod).thenReturn(return);
테스트하는 객체의 메서드 내에 mock 객체 메서드를 임의의 값으로 대입하여 동작하게 한다.
mock 객체가 정상작동했을 때를 기준으로 값을 반환하여 온전한 단위 테스트를 진행 할 수 있게된다.
any()
mock 객체 메서드의 인자로 특정값을 입력하면 그 값이 들어왔을 경우에만 정의한 출력값을 반환한다.
하지만 객체의 경우 값은 같더라도 hash 값이 다른 객체인 경우가 있다. 이때는 정상적으로 출력값을 반환해주지 못한다.
이때 특정 클래스의 어떤 값이 들어와도 정의한 출력값으로 반환하도록하기 위해 사용되는 것이 any() 메서드이다.
Mockito.when(boardRepository.save(any(Board.class))).thenReturn(givenBoard);