Ответ
Чаще всего использовал Moq — это де-факто стандарт в экосистеме .NET благодаря своей простоте и мощному API. Также знаком с NSubstitute.
Пример использования Moq для модульного теста:
Допустим, есть интерфейс репозитория и сервис, который от него зависит.
public interface IDataRepository
{
int GetImportantValue();
}
public class MyService
{
private readonly IDataRepository _repository;
public MyService(IDataRepository repository) => _repository = repository;
public int Calculate() => _repository.GetImportantValue() * 2;
}
Тест с Moq:
using Moq;
using Xunit;
public class MyServiceTests
{
[Fact]
public void Calculate_ReturnsDoubleOfRepositoryValue()
{
// 1. Arrange (Подготовка)
var mockRepo = new Mock<IDataRepository>();
// Настраиваем мок: при вызове GetImportantValue возвращает 10
mockRepo.Setup(repo => repo.GetImportantValue()).Returns(10);
var service = new MyService(mockRepo.Object);
// 2. Act (Действие)
var result = service.Calculate();
// 3. Assert (Проверка)
Assert.Equal(20, result); // Проверяем результат
// Убеждаемся, что метод репозитория был вызван ровно один раз
mockRepo.Verify(repo => repo.GetImportantValue(), Times.Once);
}
}
Ключевые преимущества Moq:
Setup()— для определения поведения мока.Verify()— для проверки взаимодействия (что метод был вызван с нужными параметрами).- Поддержка
asyncметодов, свойств, событий.
NSubstitute предлагает более лаконичный синтаксис (например, subRepo.GetValue().Returns(10)), что иногда предпочтительнее для читаемости.
Ответ 18+ 🔞
А, ну это же классика, блядь! Все эти ваши моки, тесты... Как будто без них нельзя, а на деле половина народа их нихуя не использует, но делает вид, что крутые ребята. Ладно, поехали.
Так вот, Moq — это типа как хлеб с маслом в мире .NET тестирования, его все жрут, потому что проще нихуя не придумали. Ну и NSubstitute иногда мелькает, но это уже на любителя, как горчица к тому же хлебу.
Смотри, вот тебе реальный пример, как это в жизни выглядит. Допустим, у тебя есть какой-то сервис, который тупо зависит от репозитория. Без репозитория он — как ты без утранего кофе, нихуя не работает.
public interface IDataRepository
{
int GetImportantValue();
}
public class MyService
{
private readonly IDataRepository _repository;
public MyService(IDataRepository repository) => _repository = repository;
public int Calculate() => _repository.GetImportantValue() * 2;
}
И вот ты такой думаешь: "А как мне протестить этот Calculate, если репозиторий, сука, ходит в базу, а база упала, потому что джуны опять что-то накосячили?" Вот тут-то мок и выручает, ебать его в сраку!
Смотри, как с Moq это делается:
using Moq;
using Xunit;
public class MyServiceTests
{
[Fact]
public void Calculate_ReturnsDoubleOfRepositoryValue()
{
// 1. Arrange (Готовим сцену для пиздеца)
var mockRepo = new Mock<IDataRepository>();
// Говорим муляжу: "Слушай сюда, увалень, когда тебя спросят GetImportantValue, ты говоришь '10' и не выебывайся!"
mockRepo.Setup(repo => repo.GetImportantValue()).Returns(10);
// Подсовываем сервису нашу подставную крысу
var service = new MyService(mockRepo.Object);
// 2. Act (Запускаем машинку)
var result = service.Calculate();
// 3. Assert (А теперь проверяем, не обосрался ли кто)
Assert.Equal(20, result); // Должно быть 10 * 2, а не "потому что гладиолус"
// И самое главное — тыкаем мок носом: "Ты вызывался? Ровно один раз? Говори!"
mockRepo.Verify(repo => repo.GetImportantValue(), Times.Once);
}
}
Вот и вся магия, ёпта. Setup — это чтобы накрутить мок, как тебе надо, а Verify — чтобы потом прижать его к стенке и спросить: "А ты точно вызывался, пидор? Не врёшь?".
А NSubstitute — он типа для эстетов, там синтаксис чуть короче, subRepo.GetValue().Returns(10), и всё такое. Но суть-то одна и та же — подмена реальной зависимости на свою кривую куклу, чтобы тестировать изоляцию, блядь. Выбирай, что душе угодно, лишь бы работало и не падало в три часа ночи на прод