Какую библиотеку использовал при работе с @Mock?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Аннотация @Mock и библиотека Mockito
@Mock — это аннотация из библиотеки Mockito, которая является стандартом де-факто для создания моков в Java тестировании. Это один из самых важных инструментов для unit testing.
Что такое Mockito?
Mockito — это фреймворк для создания моков (mock objects) в Unit тестах. Мок — это поддельный объект, который имитирует поведение реального объекта.
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
@Mock аннотация
@Mock создаёт мок-объект для класса. Это удобнее, чем Mockito.mock():
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testFindUserById() {
User mockUser = new User("user1", "alice@example.com");
when(userRepository.findById("user1"))
.thenReturn(Optional.of(mockUser));
User result = userRepository.findById("user1").get();
assertEquals("alice@example.com", result.getEmail());
verify(userRepository).findById("user1");
}
}
@ExtendWith MockitoExtension (рекомендуется)
@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
@Mock
private PaymentService paymentService;
@InjectMocks
private OrderService orderService;
@Test
void testCreateOrder_Success() {
User mockUser = new User("user1", "alice@example.com");
Payment mockPayment = new Payment("pay123", 99.99);
when(paymentService.processPayment(anyDouble()))
.thenReturn(mockPayment);
Order result = orderService.createOrder("user1", 99.99);
assertNotNull(result);
assertEquals("pay123", result.getPaymentId());
verify(paymentService, times(1)).processPayment(99.99);
}
}
@InjectMocks аннотация
@InjectMocks автоматически инъектирует @Mock в тестируемый класс через конструктор или setter.
Основные методы Mockito
when().thenReturn() — определить поведение
when(userRepository.findById("user1")).thenReturn(Optional.of(user));
when(userRepository.findById(anyString())).thenReturn(Optional.empty());
thenThrow() — выбросить исключение
when(userRepository.findById("invalid"))
.thenThrow(new DatabaseException("Connection failed"));
thenAnswer() — сложная логика
when(userRepository.findById(anyString()))
.thenAnswer(invocation -> {
String id = invocation.getArgument(0);
if (id.startsWith("test")) {
return Optional.empty();
}
return Optional.of(new User(id, "email"));
});
verify() — проверить вызовы
verify(userRepository, times(1)).findById("user1");
verify(userRepository).findById("user1");
verify(userRepository, never()).deleteById("user1");
verify(userRepository, atLeast(2)).findAll();
verifyNoMoreInteractions(userRepository);
anyString(), anyInt(), any() — matchers
when(userRepository.findById(anyString())).thenReturn(Optional.of(user));
when(userRepository.findById(argThat(id -> id.startsWith("admin"))))
.thenReturn(Optional.of(adminUser));
Spring Test Integration
Если используешь Spring, есть удобная аннотация @MockBean:
@SpringBootTest
public class UserControllerTest {
@MockBean
private UserService userService;
@Autowired
private TestRestTemplate restTemplate;
@Test
void testGetUser() {
User mockUser = new User("user1", "alice@example.com");
when(userService.findById("user1")).thenReturn(Optional.of(mockUser));
ResponseEntity<User> response = restTemplate.getForEntity(
"/api/v1/users/user1", User.class
);
assertEquals(HttpStatus.OK, response.getStatusCode());
assertEquals("alice@example.com", response.getBody().getEmail());
}
}
@Mock vs @Spy
@Mock — полный мок (всё поддельное)
@Mock
private UserRepository userRepository;
userRepository.findAll();
@Spy — частичный мок (реальная логика + override)
@Spy
private UserRepository userRepository = new UserRepositoryImpl();
when(userRepository.findById("user1")).thenReturn(Optional.of(user));
userRepository.findAll();
ArgumentCaptor для проверки параметров
@Test
void testPaymentAudit() {
when(bankService.transfer(100.0)).thenReturn(true);
paymentService.processPayment(100.0, "user1");
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(auditService).log(captor.capture(), anyString());
String logMessage = captor.getValue();
assertTrue(logMessage.contains("100.0"));
}
Когда использовать @Mock
Используй @Mock когда:
- Тестируешь зависимость от другого сервиса
- Не хочешь делать реальный вызов БД
- Не хочешь делать реальный HTTP запрос
- Нужно симулировать исключения
- Нужно проверить, как ваш код вызывает зависимость
Избегай @Mock когда:
- Тестируешь само поведение репозитория (используй real DB)
- Можешь обойтись без зависимости
- Зависимость не имеет сложного поведения
Практические советы
- Всегда используй @ExtendWith(MockitoExtension.class)
- Предпочитай @InjectMocks для автоинъекции
- Используй matchers для гибкости
- Проверяй взаимодействие через verify()
- Используй ArgumentCaptor для проверки параметров
Заключение
@Mock — это аннотация из Mockito, стандартного фреймворка для мокирования в Java.
Основные понятия:
- @Mock — создание мок-объекта
- @InjectMocks — автоинъекция моков
- when/then — определение поведения
- verify — проверка взаимодействия
- @ExtendWith(MockitoExtension.class) — инициализация
Mockito делает Unit тестирование проще и быстрее, позволяя изолировать код от зависимостей.