Назад к вопросам
Junior
144
questionbank
Что такое мок (mock) в тестировании?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
Мок (mock) — это объект-заглушка, полностью имитирующий поведение реального зависимого компонента или сервиса в тестовой среде. Он позволяет контролировать возвращаемые значения методов зависимостей и проверять, как тестируемый код с ними взаимодействует.
Основные отличия от других тестовых заглушек (Stubs, Fakes):
- Stub (заглушка): Предоставляет предопределенные ответы на вызовы методов, но не проверяет взаимодействие.
- Fake (фейк): Имеет работающую, но упрощенную реализацию зависимого компонента.
- Mock (мок): Имитирует поведение, предоставляет предопределенные ответы и, самое главное, позволяет верифицировать, как тестируемый код взаимодействовал с этим объектом (например, какие методы были вызваны, сколько раз, с какими аргументами).
Назначения:
- Изоляция тестируемого кода от внешних зависимостей (баз данных, внешних сервисов, файловой системы и т.д.).
- Ускорение выполнения тестов.
- Тестирование граничных случаев и обработки ошибок, которые сложно воспроизвести с реальными зависимостями.
- Верификация ожидаемого взаимодействия между объектами.
Пример использования с Mockito:
// Интерфейс, который будет мокироваться
public interface UserService {
User findUserById(long userId);
}
// Класс, который использует UserService и будет тестироваться
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
public String getUserName(long userId) {
User user = userService.findUserById(userId);
if (user != null) {
return user.getName();
}
return "User not found";
}
}
// Тестовый класс с использованием моков
import org.junit.jupiter.api.Test;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
public class UserControllerTest {
@Test
void getUserName_UserFound() {
// Создаем мок объекта UserService
UserService mockUserService = mock(UserService.class);
// Определяем поведение мока: при вызове findUserById(1), вернуть User
User mockUser = new User(1, "John Doe");
when(mockUserService.findUserById(1)).thenReturn(mockUser);
// Создаем тестируемый объект, передавая ему мок
UserController userController = new UserController(mockUserService);
// Вызываем метод, который тестируем
String userName = userController.getUserName(1);
// Проверяем результат
assertEquals("John Doe", userName);
// Верифицируем, что метод findUserById был вызван один раз с аргументом 1
verify(mockUserService, times(1)).findUserById(1);
}
@Test
void getUserName_UserNotFound() {
UserService mockUserService = mock(UserService.class);
// Определяем поведение мока: при вызове findUserById(любой long), вернуть null
when(mockUserService.findUserById(anyLong())).thenReturn(null);
UserController userController = new UserController(mockUserService);
String userName = userController.getUserName(2);
assertEquals("User not found", userName);
// Верифицируем, что метод findUserById был вызван один раз
verify(mockUserService, times(1)).findUserById(anyLong());
}
// Вспомогательный класс для примера
static class User {
private final long id;
private final String name;
public User(long id, String name) {
this.id = id;
this.name = name;
}
public long getId() { return id; }
public String getName() { return name; }
}
}