Ответ
NSubstitute — это популярная, легковесная библиотека для .NET, предназначенная для создания тестовых заглушек (mocks, stubs, spies) с очень читаемым и лаконичным синтаксисом. Она является альтернативой Moq и часто выбирается за свой "естественный" стиль.
Основные возможности:
- Создание заместителей (substitutes) для интерфейсов и классов (с виртуальными членами).
- Настройка возвращаемых значений и исключений.
- Проверка вызовов (был ли вызван, сколько раз, с какими аргументами).
- Работа с
outиrefпараметрами.
Пример сравнения: тест сервиса уведомлений
public interface INotificationService
{
void SendEmail(string to, string subject, string body);
Task<bool> SendSmsAsync(string phoneNumber, string message);
}
public class OrderProcessor
{
private readonly INotificationService _notifier;
public OrderProcessor(INotificationService notifier) => _notifier = notifier;
public void ProcessOrder(Order order)
{
// ... логика обработки ...
_notifier.SendEmail(order.CustomerEmail, "Order Confirmed", $"Your order #{order.Id} is processed.");
}
}
[Test]
public void ProcessOrder_ShouldSendConfirmationEmail()
{
// Arrange
var notificationSub = Substitute.For<INotificationService>();
var processor = new OrderProcessor(notificationSub);
var testOrder = new Order { Id = 777, CustomerEmail = "test@example.com" };
// Act
processor.ProcessOrder(testOrder);
// Assert
// Проверяем, что SendEmail был вызван 1 раз с конкретными аргументами
notificationSub.Received(1).SendEmail(
"test@example.com",
"Order Confirmed",
"Your order #777 is processed."
);
// Проверяем, что асинхронный метод SendSmsAsync НЕ вызывался
notificationSub.DidNotReceive().SendSmsAsync(Arg.Any<string>(), Arg.Any<string>());
}
// Пример настройки возвращаемого значения
[Test]
public async Task CheckStatus_ShouldReturnTrue_WhenSmsSentSuccessfully()
{
var service = Substitute.For<INotificationService>();
// Настраиваем асинхронный метод на возврат true
service.SendSmsAsync("+79001234567", "Hello").Returns(Task.FromResult(true));
bool result = await service.SendSmsAsync("+79001234567", "Hello");
Assert.That(result, Is.True);
}
Плюсы NSubstitute:
- Читаемый синтаксис:
Received(),DidNotReceive(),Returns()выглядят как часть утверждения. - Умные сопоставления аргументов:
Arg.Any<string>(),Arg.Is<string>(s => s.Contains("test")). - Хорошая документация и активное сообщество.