Какую библиотеку используют для создания моков (mock-объектов) в C#?

«Какую библиотеку используют для создания моков (mock-объектов) в C#?» — вопрос из категории Тестирование, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В экосистеме .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 остается стандартом де-факто для большинства проектов из-за зрелости и обширного сообщества.