mockito를 이용한 TodoService 테스트
@ExtendWith(MockitoExtension.class)
class TodoServiceTest implements TodoTest {
@InjectMocks
TodoService todoService;
@Mock
TodoRepository todoRepository;
@DisplayName("할일 생성")
@Test
void createTodo() {
// given
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.save(any(Todo.class))).willReturn(testTodo);
// when
var result = todoService.createTodo(TEST_TODO_REQUEST_DTO, TEST_USER);
// then
var expect = new TodoResponseDto(testTodo);
assertThat(result).isEqualTo(expect);
}
@DisplayName("할일 DTO 조회")
@Test
void getTodoDto() {
// given
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
// when
var result = todoService.getTodoDto(TEST_TODO_ID);
// then
assertThat(result).isEqualTo(new TodoResponseDto(testTodo));
// isEqualTo : 주소값을 기준으로 비교
// 필드값을 비교하기 위해서 TodoResponseDto에서 @EqualsAndHashCode(callSuper = false)
// @EqualsAndHashCode : Equals에 HashCode를 기준으로 비교
// Hash코드는 어노테이션을 통해 HashCode메서드가 자동으로 생성되는데 그 메서드는 필드값을 변환한 것
// 주소값 상관없이 필드값만 같으면 같은 HashCode가 나옴
// 같은 TEST_TODO_ID를 사용했기때문에 true
}
@DisplayName("할일 리스트 맵 (최신순 정렬)")
@Test
void getUserTodoMap() {
// given
var testTodo1 = TodoTestUtils.get(TEST_TODO, 1L, LocalDateTime.now(), TEST_USER);
var testTodo2 = TodoTestUtils.get(TEST_TODO, 2L, LocalDateTime.now().minusMinutes(1), TEST_USER);
var testAnotherTodo = TodoTestUtils.get(TEST_TODO, 1L, LocalDateTime.now(), TEST_ANOTHER_USER);
given(todoRepository.findAll(any(Sort.class))).willReturn(List.of(testTodo1, testTodo2, testAnotherTodo));
// when
var result = todoService.getUserTodoMap();
// then
assertThat(result.get(new UserDto(TEST_USER)).get(0)).isEqualTo(new TodoResponseDto(testTodo1));
assertThat(result.get(new UserDto(TEST_USER)).get(1)).isEqualTo(new TodoResponseDto(testTodo2));
assertThat(result.get(new UserDto(TEST_ANOTHER_USER)).get(0)).isEqualTo(new TodoResponseDto(testAnotherTodo));
}
@DisplayName("할일 수정")
@Test
void updateTodo() {
// given
ReflectionTestUtils.setField(TEST_USER, User.class, "id", TEST_USER_ID, Long.class);
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
// when
var request = new TodoRequestDto("updateTitle", "updateContent");
var result = todoService.updateTodo(TEST_TODO_ID, request, TEST_USER);
// then
assertThat(result).isEqualTo(new TodoResponseDto(testTodo));
}
@DisplayName("할일 완료 처리")
@Test
void competeTodo() {
// given
// id 설정
ReflectionTestUtils.setField(TEST_USER, User.class, "id", TEST_USER_ID, Long.class);
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
// when
var result = todoService.completeTodo(TEST_TODO_ID, TEST_USER);
// then
assertThat(result.getIsCompleted()).isEqualTo(true);
}
@DisplayName("할일 조회")
@Test
void getTodo() {
// given
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
// when
var result = todoService.getTodo(TEST_TODO_ID);
// then
assertThat(result).isEqualTo(testTodo);
}
@DisplayName("유저의 할일 조회")
@Nested
class getUserTodo {
@DisplayName("유저의 할일 조회 성공")
@Test
void getUserTodo_success() {
// given
ReflectionTestUtils.setField(TEST_USER, User.class, "id", TEST_USER_ID, Long.class);
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
// when
var result = todoService.getUserTodo(TEST_TODO_ID, TEST_USER);
// then
assertThat(result).isEqualTo(testTodo);
}
@DisplayName("유저의 할일 조회 실패 - 조회 권한 없음")
@Test
void getUserTodo_fail() {
// given
ReflectionTestUtils.setField(TEST_USER, User.class, "id", TEST_USER_ID, Long.class);
var testTodo = TodoTestUtils.get(TEST_TODO, TEST_USER);
given(todoRepository.findById(eq(TEST_TODO_ID))).willReturn(Optional.of(testTodo));
ReflectionTestUtils.setField(TEST_ANOTHER_USER, User.class, "id", TEST_ANOTHER_USER_ID, Long.class);
// when & exception
assertThrows(RejectedExecutionException.class, () -> todoService.getUserTodo(TEST_TODO_ID, TEST_ANOTHER_USER));
}
}
}
@ExtendWith()를 통해 단위 테스트에 사용할 확장 기능을 선언하고 MockitoExtension.class를 통해 Spring Test Context 프레임워크와 Junit5와 통합해서 사용한다.
@Mock : Mock 객체를 생성
@InjectMocks : @Mock으로 생성된 객체를 자동으로 주입
