: 가짜 객체(Fake)를 생성하여 행동만 정의하고 내부 로직은 모두 비워진 객체로, 실제 로직은 수행되지 않으며, 호출 여부나 횟수 등을 검증하는 용도로 사용한다. 모든 메서드가 기본값을 반환한다.(null, 0, false 등)
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
EmailSender emailSender; // send 메서드는 진짜 호출되지 않음
@InjectMocks
UserService userService;
@Test
void testEmailIsSent() {
userService.registerUser("test@example.com");
verify(emailSender).send("test@example.com"); // send 호출 여부만 확인
}
}
: 가짜 객체에 대해 특정 메서드 호출 시 미리 정의한 값을 반환하도록 설정. 즉, "무엇을 반환할지"를 고정하는 방식이다. Mock/Spy와 함께 사용한다. ex) when().thenReturn() ...
@Test
void testExistingUserLogin() {
User mockUser = new User("test@example.com");
when(userRepository.findByEmail("test@example.com"))
.thenReturn(mockUser); // 특정 입력에 대해 결과를 고정 (Stub)
User user = userService.login("test@example.com");
assertEquals("test@example.com", user.getEmail());
}
: 실제 객체를 감싸서, 일부는 진짜로 호출하고 일부는 조작할 수 있는 부분 Mock으로, 원래 동작을 유지하면서도 특정 메서드만 가로채거나 검증이 가능하다.
class Calculator {
public int add(int a, int b) { return a + b; }
public int multiply(int a, int b) { return a * b; }
}
@Spy
Calculator calculator = new Calculator();
@Test
void testSpyPartialStub() {
doReturn(10).when(calculator).add(3, 5); // add만 조작
int result = calculator.add(3, 5); // 10이 반환됨
int mul = calculator.multiply(2, 3); // 실제 multiply는 호출됨
assertEquals(10, result);
assertEquals(6, mul);
}
이처럼 Mockito의 다양한 방식은 각각의 목적과 역할이 분명히 구분되므로, 이를 상황에 맞게 판단하고 일관성 있게 적용하는 것이 중요하다.
https://www.browserstack.com/guide/mockito-spy-vs-mockito-mock
https://kimjongmo.github.io/spring/mock-vs-spy