Ответ
В экосистеме .NET для создания моков (mock-объектов) в юнит-тестах наиболее популярной и широко используемой библиотекой является Moq. Она предоставляет интуитивно понятный fluent-синтаксис для настройки поведения зависимостей.
Пример использования Moq:
// Интерфейс зависимости
public interface IDataRepository
{
int GetRecordCount();
}
// Класс, который тестируем
public class ReportService
{
private readonly IDataRepository _repository;
public ReportService(IDataRepository repository) => _repository = repository;
public bool HasData() => _repository.GetRecordCount() > 0;
}
// Юнит-тест с Moq
[Test]
public void HasData_ReturnsTrue_WhenRepositoryHasRecords()
{
// 1. Arrange (Подготовка)
var mockRepository = new Mock<IDataRepository>();
// Настраиваем мок: при вызове GetRecordCount() возвращаем 5
mockRepository.Setup(repo => repo.GetRecordCount()).Returns(5);
var service = new ReportService(mockRepository.Object);
// 2. Act (Действие)
bool result = service.HasData();
// 3. Assert (Проверка)
Assert.IsTrue(result);
// Дополнительная проверка, что метод был вызван ровно один раз
mockRepository.Verify(repo => repo.GetRecordCount(), Times.Once);
}
Почему Moq?
- Простота: Легко осваивается и читается.
- Строгая типизация: Настройки и проверки привязаны к сигнатурам методов интерфейса, что предотвращает ошибки.
- Богатый функционал: Поддержка последовательных возвращаемых значений (
ReturnsAsync,Throws), проверка аргументов (It.IsAny<int>(),It.Is<int>(x => x > 0)), кастомизация.
Альтернативные библиотеки:
- NSubstitute: Имеет более лаконичный синтаксис (например,
sub.GetCount().Returns(5)). - FakeItEasy: Известен простым API для создания заглушек (fakes).
Выбор между ними часто сводится к личным предпочтениям команды, но Moq остается стандартом де-факто для большинства проектов из-за зрелости и обширного сообщества.