@Service Layer는 통상 @Repository에 의존한다. 즉 @Repository가 없으면 컴파일조차 할 수가 없다.
@Service
@RequiredArgsConstructor
public class BoardService {
private final BoardRepository repo;
public Board write(Board board) {
return repo.save(board);
}
public Optional<Board> select(long boardNo) {
return repo.findById(boardNo);
}
}
하지만 @Service에 대한 테스트는 @Repository에 대한 테스트가 아니기 때문에 진짜 @Repository가 필요하지는 않고 완벽하게 동작하는 @Repository가 존재한다고 생각하고 진행한다. 이 완벽하게 동작하는 @Repository를 만들기 위해서 가짜 객체인 Mock을 사용한다.
Mock을 만들 때 Junit에서 직접 MockitoExtension을 확장하는 방식과 SpringBootTest에서 사용하는 방식이 가능하다.
@SpringBootTest(classes = BoardService.class) // 필요한 빈(테스트 대상)만 로딩
public class T_9312_TestMockAndSpyBean2 {
@MockBean
BoardRepository repo; // 존재하지 않는 녀석을 새로 구성
@Autowired
BoardService service;
private Board board;
@BeforeEach
public void setup() {
board = Board.builder().boardNo(1L).writer("hong").content("sample").build();
}
@Test
public void saveTest() {
// given - 조건 및 setup
when(repo.save(board)).thenReturn(board);
// when - 테스트 하려는 행동
Board result = service.write(board);
// then - 결과 검증
assertEquals(result, board);
}
@Test
public void selectTest() {
// given - 조건 및 setup
when(repo.findById(2L)).thenReturn(Optional.empty());
when(repo.findById(1L)).thenReturn(Optional.of(board));
// when - 테스트 하려는 행동
Optional<Board> result = service.select(2L);
// then - 결과 검증
assertTrue(result.isEmpty());
// when
result = service.select(1L);
assertEquals(result.get(), board);
}
}