Где задаётся поведение объектов в тестах?

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

Ответ

Поведение объектов-заглушек (моков и стабов) задаётся в коде теста с помощью методов настройки, предоставляемых библиотеками для мокинга, такими как Moq, NSubstitute или FakeItEasy.

Основные места и способы:

  1. В методе Setup() (или его аналоге) для определения того, какой метод или свойство будет подменяться.
  2. Цепочкой методов, следующих за Setup(), таких как:
    • .Returns(value) — чтобы заглушка возвращала конкретное значение.
    • .Throws(exception) — чтобы заглушка выбрасывала исключение.
    • .Callback() — чтобы выполнить дополнительное действие при вызове.

Пример настройки мока с Moq:

// Создаём мок интерфейса IRepository
var mockRepository = new Mock<IRepository>();

// Задаём поведение для метода GetById
// Он будет возвращать тестовый объект при любом целочисленном аргументе
mockRepository
    .Setup(repo => repo.GetById(It.IsAny<int>()))
    .Returns(new Product { Id = 42, Name = "Test Product" });

// Используем мок в тестируемом сервисе
var service = new ProductService(mockRepository.Object);
var result = service.GetProductDetails(42);

// Проверяем, что сервис корректно обработал данные от заглушки
Assert.Equal("Test Product", result.Name);
// Проверяем, что метод был вызван ровно один раз
mockRepository.Verify(repo => repo.GetById(42), Times.Once);

Ключевые моменты:

  • It.IsAny<T>() используется для соответствия любому аргументу указанного типа.
  • It.Is<T>(predicate) позволяет задать условие для аргумента.
  • Метод Verify() используется для утверждений (assertions) о том, как и сколько раз был вызван метод мока.