Intellij
@Mock 어노테이션을 사용하여 Mock 객체를 생성하고, 특정 메서드 호출에 대한 동작을 정의합니다.| Mock | Spy |
|---|---|
| 실제 객체를 대체하여, 모든 메서드를 모킹합니다. | 실제 객체를 사용하고, 특정 메서드만 모킹할 수 있습니다. |
| 모든 메서드가 Mockito에서 정의한 동작을 따릅니다. | 스파이된 메서드만 모킹되며, 나머지 메서드는 실제 동작을 따릅니다. |
| 메서드 호출 및 동작을 모두 정의해야 합니다. | 전체 객체의 상태와 동작을 유지하면서, 선택적으로 동작을 제어할 수 있습니다. |
| 의존성 주입된 실제 객체와는 완전히 독립적입니다. | 실제 객체의 일부 동작을 테스트하는 데 유리합니다. |
- Mock 객체 사용하기 - @Mock 어노테이션을 사용
- 주입된 의존성을 Mock 객체로 대체하여 테스트
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void givenValidUser_whenRegister_thenUserIsSaved() {
// Given
User user = new User("john.doe", "password123", "john.doe@example.com");
when(userRepository.save(any(User.class))).thenReturn(user);
// When
User registeredUser = userService.register(user);
// Then
assertNotNull(registeredUser);
assertEquals("john.doe", registeredUser.getUsername());
verify(userRepository, times(1)).save(user);
}
}
@Mock: userRepository를 모킹하여, 데이터베이스와의 실제 상호작용 없이 테스트합니다.@InjectMocks: UserService에 모킹된 UserRepository를 주입합니다.when(userRepository.save(any(User.class))): save() 메서드를 호출할 때, 실제로는 Mock 객체의 가짜 데이터를 반환하도록 설정합니다.verify(userRepository, times(1)).save(user): save() 메서드가 정확히 한 번 호출되었는지 검증합니다.- Spy 객체 사용하기
- 실제 객체를 기반으로 동작하며, 객체의 일부 메서드만 모킹
@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
@Spy
private OrderService orderService;
@Test
void givenValidOrder_whenProcessOrder_thenOrderIsProcessed() {
// Given
Order order = new Order("item1", 2);
doReturn(100.0).when(orderService).calculatePrice(order);
// When
double price = orderService.processOrder(order);
// Then
assertEquals(100.0, price);
verify(orderService, times(1)).calculatePrice(order);
}
}
@Spy: 실제 OrderService 객체를 사용하면서, calculatePrice() 메서드만 모킹합니다.doReturn(100.0).when(orderService).calculatePrice(order): 실제로 calculatePrice() 메서드를 호출하지 않고, 100.0을 반환하도록 설정합니다.@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
@Mock
private PaymentService paymentService;
@InjectMocks
private OrderService orderService;
@Test
void givenValidOrder_whenProcessOrder_thenPaymentIsProcessed() {
// Given
Order order = new Order("item1", 2);
when(paymentService.processPayment(anyDouble())).thenReturn(true);
// When
boolean isPaymentSuccessful = orderService.processOrder(order);
// Then
assertTrue(isPaymentSuccessful);
verify(paymentService, times(1)).processPayment(anyDouble());
}
}
paymentService의 processPayment() 메서드가 항상 true를 반환하도록 모킹합니다.processOrder() 메서드를 호출하여 주문을 처리합니다.processPayment() 메서드가 한 번 호출되었는지 검증합니다.- Spy를 활용한 Given-When-Then 테스트
@ExtendWith(MockitoExtension.class)
public class PaymentServiceTest {
@Spy
private PaymentService paymentService;
@Test
void givenValidAmount_whenProcessPayment_thenPaymentIsProcessedSuccessfully() {
// Given
double amount = 200.0;
doReturn(true).when(paymentService).validateAmount(amount);
// When
boolean isPaymentSuccessful = paymentService.processPayment(amount);
// Then
assertTrue(isPaymentSuccessful);
verify(paymentService, times(1)).validateAmount(amount);
}
}
validateAmount() 메서드만 모킹하여 항상 true를 반환하도록 설정합니다.processPayment() 메서드를 호출합니다.validateAmount() 메서드가 호출되었는지 검증합니다.