Ответ
Mock (Мок) — это объект-заглушка, который в тестах заменяет реальную зависимость. Его основная цель — изолировать тестируемый модуль, контролировать поведение зависимостей и проверять взаимодействие с ними (какие методы были вызваны, с какими аргументами и сколько раз).
Зачем это нужно?
- Изоляция: Тестируете только логику конкретного класса, а не работу базы данных, внешнего API или файловой системы.
- Контроль: Можете легко смоделировать любые сценарии — успешное выполнение, ошибки, долгие ответы.
- Верификация: Убедиться, что ваш код корректно взаимодействует с другими компонентами.
Пример на C# с библиотекой Moq:
// Интерфейс зависимости (например, репозиторий)
public interface IUserRepository
{
User GetById(int id);
void Save(User user);
}
// Класс, который мы тестируем (сервис)
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository) => _repository = repository;
public string ActivateUser(int userId)
{
var user = _repository.GetById(userId);
user.IsActive = true;
_repository.Save(user);
return $"User {user.Name} activated.";
}
}
// Сам тест с использованием Moq
[Test]
public void ActivateUser_ShouldActivateAndSaveUser()
{
// 1. Arrange (Подготовка)
var mockRepo = new Mock<IUserRepository>();
var testUser = new User { Id = 1, Name = "Alice", IsActive = false };
// Настраиваем мок: при вызове GetById с аргументом 1 вернуть testUser
mockRepo.Setup(repo => repo.GetById(1)).Returns(testUser);
var service = new UserService(mockRepo.Object);
// 2. Act (Действие)
var result = service.ActivateUser(1);
// 3. Assert (Проверка)
Assert.That(result, Is.EqualTo("User Alice activated."));
Assert.That(testUser.IsActive, Is.True);
// Верификация: метод Save был вызван ровно 1 раз с конкретным объектом user
mockRepo.Verify(repo => repo.Save(testUser), Times.Once);
}
Ключевые методы Moq:
Setup()— задаёт поведение мока (что возвращать при вызове).Returns()— определяет возвращаемое значение.Verify()— проверяет, был ли вызов метода с ожидаемыми параметрами.
Ответ 18+ 🔞
Да ты посмотри, что эти умники придумали — Mock, или по-нашему «Мок». Это ж типа такая заглушка, подстава для тестов. Суть в чём: ты берёшь свою зависимость — ну там базу данных, какой-нибудь внешний сервис, который тебе на работу мешает, — и подменяешь её этой самой заглушкой. Чтобы тестировать только свою логику, а не весь этот огород вокруг.
А нахуя это вообще надо?
- Изоляция: Чтобы не париться, что база данных упала, API сдохло или файловая система глючит. Тестируешь только свой код, а не всю вселенную.
- Контроль: Можешь накрутить моку любое поведение — хоть успешный ответ, хоть ошибку, хоть долгий таймаут. Всё как в жизни, только под твоим управлением.
- Верификация: Можешь потом проверить, а вызывал ли твой код вообще этот мок, с какими аргументами и сколько раз. Чтобы не получилось, что ты думаешь, что всё работает, а на самом деле ни один метод не дернулся.
Смотри пример на C# с библиотекой Moq:
// Интерфейс зависимости (ну, типа репозиторий)
public interface IUserRepository
{
User GetById(int id);
void Save(User user);
}
// Класс, который мы тестируем (сервис, где вся логика)
public class UserService
{
private readonly IUserRepository _repository;
public UserService(IUserRepository repository) => _repository = repository;
public string ActivateUser(int userId)
{
var user = _repository.GetById(userId);
user.IsActive = true;
_repository.Save(user);
return $"User {user.Name} activated.";
}
}
// А вот сам тест, где мы и используем Moq
[Test]
public void ActivateUser_ShouldActivateAndSaveUser()
{
// 1. Arrange (Готовим поле для драки)
var mockRepo = new Mock<IUserRepository>();
var testUser = new User { Id = 1, Name = "Alice", IsActive = false };
// Настраиваем мок: когда вызовут GetById с единичкой — вернуть нашего тестового юзера
mockRepo.Setup(repo => repo.GetById(1)).Returns(testUser);
var service = new UserService(mockRepo.Object);
// 2. Act (Делаем, что должны)
var result = service.ActivateUser(1);
// 3. Assert (Проверяем, что натворили)
Assert.That(result, Is.EqualTo("User Alice activated."));
Assert.That(testUser.IsActive, Is.True);
// А вот это важное: проверяем, что метод Save вызвался ровно один раз с нашим юзером
mockRepo.Verify(repo => repo.Save(testUser), Times.Once);
}
Основные приёмы в Moq, которые надо знать:
Setup()— этим ты говоришь моку: «Слушай сюда, когда будут вызывать такой-то метод, веди себя вот так».Returns()— а этим уточняешь: «И вот это вот возвращай, понял?».Verify()— это уже после драки проверка: «Так, пацан, а вызывал ли ты вообще метод Save, и если да, то сколько раз и с чем?». Без этого вообще смысла нет.