첫번째,
ServiceTest 클래스 상단에 모키토 선언,
안에 테스트 대상인 service에 @InjectMocks 선언,
테스트 시 주입될 클래스는 레포지토리이므로 @Mock 선언,
두번째,
이후에는 각 메서드 마다 단위테스트를 만드는데 이때,
(예를들어 create)
AAA패턴에 맞게 given, when, then.
given으로 입력될 데이터를 미리 대본처럼 만들고,
when으로 서비스의 메서드를 호출하고,
then의 assert/verify를 이용하여 결과값/메서드가 잘 반환/실행 되었는지 테스트한다.
기본 세팅 핵심 개념 3개
1. Mock : 가짜 객체
2. Stubbing : 대본 써주는 것(이 메서드가 호출되면 이렇게 답해!)
3. Verify(검증) : 호출 자체를 확인(정말 그 메서드를 그 횟수만큼 불럿나?)
@ExtendWith(MockitoExtension.class) : 모키토 준비 완료!@Mock : 가짜 객체 표시, ServiceTest 단에서는 Repository가 가짜로 만들어진다.@InjectMocks : 진짜로 테스트할 대상, Service를 테스트할 예정이므로 @InjectMocks
BoardService boardService;
AAA패턴 : 테스트의 뼈대
1. Given(준비) : 입력 데이터 만들기
2. When(실행) : 서비스 메서드 호출
3. Then(검증) : 리턴값 검사(assert...) + 레포지토리 호출 검사(verify...)
given(mock.메서드(인자))).willReturn(값);
given(mock.메서드(인자))).willThrow(예외);
verify(mock, times(1)).메서드(인자);
verify(mock, never()).메서드(...);
verifyNoMoreInteractions(mock); <= 더 이상 건드리지 않았는지.
assertNotNull(x);
assertEquals(a, b);
assertThrows(예외.class, ()-> 실행);
any(Board.class)
anyString()
eq("고정값")
doThrow(new SomeEx()).when(mock).voidMethod(args);
내가 작성한 Create Test
Users users = mock(Users.class);
given(usersRepository.findByUsername("tester")).willReturn(Optional.of(users));
given(users.getUserId()).willReturn(10L);
given(boardRepository.existsByTitle("제목")).willReturn(false);
given(boardRepository.save(any(Board.class))).willReturn(
new Board(1L, 10L, "제목", "내용", LocalDateTiem.now(), LocalDateTime.now())
);
BoardCreateDto result = boardService.create(boardCreateCommand, "tester");
assertNotNull(result);
assertEquals("제목", result.getTitle());
assertEquals("내용", result.getContent());
verify(usersRepository, times(1)).findByUsername("tester");
verify(boardRepository, times(1)).existsByTitle("제목");
verify(boardRepository, times(1)).save(any(Board.class));
여기까지가 완벽한 AAA 패턴이라고 볼 수 있다.