@Mock, @InjectMocks, @Spy)으로 모의 객체를 생성/주입할 수 있게 해주는 어노테이션@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
// 테스트 대상 메소드에서 PlantService.save 메소드가 호출되었는지 검증
verify(plantService).save(plant);
// 특정 횟수로 호출되었는지 검증
verify(plantService, times(1)).save(plant);
// 다른 메서드 호출이 없어야 함을 검증
verifyNoMoreInteractions(plantService);
특정 메서드가 호출될 때 반환할 값이나 예외 정하기
// 반환값 지정
when(plantService.findById(plantId)).thenReturn(new Plant("몬스테라"));
// 예외
when(plantService.findById(plantId)).thenThrow(NoSuchElementException.class);
예상한 동작이 실제로 일어나는지를 검증
static import해서 쓰면 편하다.
expected, actual 순으로 파라미터로 넘겨주면 됨
assertEquals("expected result", result);
assertTrue(result);
assertFalse(result);
assertNotNull(result);
Executable executable = () -> repotCommandService.getRepotByRepotIdAndGardenerId(repotId, gardenerId);
UnauthorizedAccessException e = assertThrows(UnauthorizedAccessException.class, executable);
assertEquals(ExceptionCode.NOT_YOUR_REPOT, e.getCode());
단순히 해당 Exception이 발생하는지 검사하려면 assertThrows(예외, 람다) 정도면 충분하지만,
Exception 내부도 검사하고 싶거나 코드가 너무 길어 나눠서 쓰고 싶다면 위처럼 하면 된다.
동일한 테스트 메서드를 여러 다른 입력값으로 실행하여 반복 테스트하기
@ParameterizedTest
@ValueSource(ints = {1, 2, 3, 4, 5})
void testIsPositive(int number) {
assertTrue(number > 0);
}
ints 배열에 있는 각각의 값들을 number 매개변수로 넘겨주고, 이 값을 검증하여 양수인지를 확인
인자를 제공하는 메서드를 지정
@ParameterizedTest
@MethodSource("provideNumbers")
void testIsPositive(int number) {
assertTrue(number > 0);
}
static Stream<Integer> provideNumbers() {
return Stream.of(1, 2, 3, 4, 5);
}
인자를 제공하는 클래스 지정
@ParameterizedTest
@ArgumentsSource(MyArgumentsProvider.class)
void testIsPositive(int number) {
assertTrue(number > 0);
}
static class MyArgumentsProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
return Stream.of(
Arguments.of(1),
Arguments.of(2),
Arguments.of(3),
Arguments.of(4),
Arguments.of(5)
);
}
}
| @MethodSource | @ArgumentSource |
|---|---|
| "메소드 이름" | MyArgumentsProvider.class |
| return Stream<해당 타입> | implements ArgumentsProvider |
테스트 이름 짓기
Mock Object 메서드가 호출 시 아무 작업도 하지 않도록 설정
주로 void 메서드가 호출 시 활용
doNothing().when(gardenerRepository).delete(anyLong());
실제로 데이터베이스에서 사용자를 삭제하지 않고, 단순히 메서드 호출 여부만을 검증할 수 있음
- 테스트 클래스 세팅
- 클래스 어노테이션으로 @ExtendWith(MockitoExtension.class)
- 혹은 @BeforeEach 메소드 작성
- 테스트 대상 클래스에 @InjectMock
- 테스트 대상 클래스의 의존관계 클래스에 @Mock
- 테스트 클래스 설정
- @Test: 기본 테스트
- @ParameterizedTest: 각기 다른 테스트 데이터를 사용해 테스트
- @MethodSource("메소드 이름"): 메소드를 통해 인자 제공
- @ArgumentProvider(대상 클래스명.class): 클래스를 통해 인자 제공
- Given(주어진 상황)
- 테스트 대상 객체, 상태 정의, 입력값 생성
- stubbing
- when().thenReturn()
- when().thenThrow()
- When(실행)
GardenerDetail result = gardenerService.update(request);- Then(검증)
- Assertions
- assertEqual, assertTrue, assertFalse, assertNotNull ...
- verify
- verify(plantService, times(1)).save(plant);
- verifyNoMoreInteractions(plantService);