Как проверить интеграцию между промежуточным программным обеспечением для обработки глобальных ошибок и моим контроллером в ASP.Net Core? - PullRequest
0 голосов
/ 14 октября 2019

Я пытаюсь написать какой-нибудь тест для XUnit, в частности, мне бы хотелось иметь тест, который бы гарантировал, что при возникновении определенного исключения он будет преобразован в значимый код ошибки. Я уже настроил глобальную промежуточную программу обработки ошибок, и она работает правильно. Ниже приведен пример кода, показывающего, как работает мое решение:

Мой контроллер с конечной точкой почты, который может возвращать 200 или 404

//Controller
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(404)]
public async Task<StatusCodeResult> Create([FromBody] Request request) {
    //Process request
    handler.Handle(request);
    return Ok();
}

Промежуточное программное обеспечение для глобальной обработки ошибок, которое преобразует исключения вКоды ошибок

//StartUp Middleware
app.UseExceptionHandler(builder => {
    builder.Run(handler: async context => {
        IExceptionHandlerFeature error = context.Features.Get<IExceptionHandlerFeature>();
        if (error != null) {
            int statusCode = (int)GetStatusCodeForException(error.Error);
            context.Response.StatusCode = statusCode;
            context.Response.ContentType = "application/json";

            await context.Response.WriteAsync(new ErrorDetails { StatusCode = statusCode, Message = error.Error.Message }.ToString());
        }
    });
});

И затем мой тест, в котором я устраиваю некоторые макеты, создаю экземпляр контроллера и вызываю метод Create

//UnitTest
[Fact]
public async Task Test()
{
    //Arrange
    var mockHandler = new Mock<IHandler>();
    mockHandler.Setup(handler => handler.Handle(It.IsAny<Request>())).Throws(new CustomException(It.IsAny<string>()));

    MyController myController = new MyController();

    //Act
    var statusCodeResult = await myController.Create(request);

    //Assert
    StatusCodeResult result = Assert.IsType<NotFoundResult>(statusCodeResult);
}

Здесь я хочу убедиться, что CustomException переназначен вкод состояния 404. Как это сделать? Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

Вы можете использовать класс WebApplicationFactory из пакета nuget Microsoft.AspNetCore.Mvc.Testing. Это загружает ваше приложение в память, чтобы обеспечить сквозные функциональные тесты. Вместо того, чтобы вызывать отдельные методы действий, вы можете делать вызовы через HttpClient, чтобы гарантировать, что все промежуточное ПО и т. Д. Вызывается.

Вы используете класс Startup, который вы уже определили в своем основном проекте ввода, и можете добавить mock /подделка объектов в контейнер IoC по мере необходимости. Это позволяет вам проверить / настроить любые зависимости.

Затем вы можете ввести это как IClassFixture. Однажды введенный вызов .CreateClient() в экземпляре вернет HttpClient, через который вы можете делать запросы.

Вот пример реализации:

// app factory instance
public class TestAppFactory : WebApplicationFactory<Startup>
{
    // mock for setup/verify
    public Mock<IHandler> MockHandler { get; } = new Mock<IHandler>();

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureTestServices(services =>
        {
            services.AddSingleton(MockHandler);
        });
    }
}

public class MyTestClass : IClassFixture<TestAppFactory>
{
    private readonly TestAppFactory _factory;
    private readonly HttpClient _client;
    private readonly Mock<IHandler> _mockHandler;

    public MyTestClass(TestAppFactory factory)
    {
        _factory = factory;
        _client = factory.CreateClient();
        _mockHandler = factory.MockHandler;
    }

    [Fact]
    public async Task Test()
    {
        // make calls via _client
    }
}
0 голосов
/ 14 октября 2019

В вашем тесте промежуточное программное обеспечение недоступно. Для этого вам нужно раскрутить среду хостинга, пакет Microsoft.AspNetCore.TestHost предоставляет вам ту, которую вы можете использовать для тестирования:

[Fact]
public async Task Test1()
{
    using var host = new TestServer(Program.CreateHostBuilder(null));
    var client = host.CreateClient();

    var requestMessage = new HttpRequestMessage(HttpMethod.Get, "/api/controller");

    var result = await client.SendAsync(requestMessage);

    var status = result.StatusCode;

    // TODO: assertions
}

Теперь, когда вы вызываете свой API способом, выдается исключение, промежуточное программное обеспечение должно быть выполнено и закрыто.

...