Промежуточное ПО для модульного тестирования с NUnit и NSubstitute - PullRequest
0 голосов
/ 10 мая 2018

Я написал немного Middleware на сайте AspNetCore, и я пытаюсь провести его модульное тестирование, в основном, следуя этому руководству , в котором используется Moq.

Моя проблема заключается в поискеэквивалент NUnit / NSubstitute для new DefaultHttpContext().Подстановка HttpContext вызовет промежуточное программное обеспечение, но оно пропустит try.Я предполагаю, что это из-за проблемы, указанной ниже.Есть ли в NUnit функция для создания реального HttpContext или я смотрю на гораздо большую инфраструктуру для достижения этой цели?

Я отправляю экземпляр DefaultHttpContext в метод Invoke.Я не могу использовать поддельный HttpContext в этом сценарии, потому что первая промежуточная программа (лямбда-функция, которую мы передали конструктору) должна будет записать в ответ.Следовательно, HttpResponse должен быть реальным объектом, который не подвергается макету.

Вот код для моего теста

[TestFixture]
public class ExceptionHelperTests
{
    private IErrorRepository errorRepository;
    private ExceptionHandler handler;

    [SetUp]
    public void Setup()
    {
        errorRepository = Substitute.For<IErrorRepository>();
    }

    [Test]
    public async void Given_AnExceptionHappens_Then_ItShouldBeLogged()
    {
        // Arrange
        const string username = "aUser";
        var user = Substitute.For<ClaimsPrincipal>();
        user.Identity.Name.Returns(username);

        handler = new ExceptionHandler(
            next: async (innerHttpContext) =>
            {
                innerHttpContext.User = user;
            }, 
            repository: errorRepository);

        // Act
        await handler.Invoke(new DefaultHttpContext());

        // Assert
        errorRepository.Received().LogException(Arg.Any<string>(), Arg.Any<Exception>(), Arg.Is(username));
    }
}

Вот IErrorRepository

    public interface IErrorRepository
{
    Exception LogException(string message, Exception ex, string userId);
    void LogMessage(string message, string errorDetail, string userId);
}

А вот и промежуточное ПО (с упрощенным HandleException)

public sealed class ExceptionHandler
    {
        private readonly RequestDelegate _next;
        private readonly IErrorRepository repository;

        public ExceptionHandler(RequestDelegate next, IErrorRepository repository)
        {
            _next = next;
            this.repository = repository;
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (Exception ex)
            {
                HandleException(ex, context.User.Identity.Name);
            }
        }

        public void HandleException(Exception ex, string userId)
        {
            repository.LogException("An unhandled exception has occurred.", ex, userId);
        }
    }

1 Ответ

0 голосов
/ 10 мая 2018

DefaultHttpContext - просто реализация по умолчанию абстрактного класса HttpContext.

Вы просто могли бы сделать

var HttpContextSub = Substitute.For<HttpContext>();
...