Как проверить правильность внедрения зависимостей всех основных контроллеров ASP.NET? - PullRequest
0 голосов
/ 11 июня 2018

У нас иногда возникают проблемы, когда кто-то добавляет некоторый DI в контроллер, но забывает добавить соответствующую строку в Startup.cs для установки области объекта.

Это не мешает запуску приложения, носкорее, выдает исключение при достижении соответствующей конечной точки.

Есть ли какой-либо способ программной проверки всех контроллеров на предмет корректности и предотвращения запуска приложения в противном случае?

В качестве альтернативы есть простой способнаписать универсальный автоматический тест для проверки того, что каждый контроллер может быть создан с использованием указанного DI в Startup.cs?

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

Лучший метод - бросить ArgumentNullException с.Например, в конструкторе вашего контроллера:

_foo = foo ?? throw new ArgumentNullException(nameof(foo));

Это приведет к сбою любого действия в контроллере (каждый раз, когда создается контроллер), если зависимость не удовлетворена.Затем, если у вас есть какой-либо набор интеграционных тестов для этого контроллера, все ваши тесты мгновенно потерпят неудачу, и вы не будете точно знать, почему: аргумент конструктора не был выполнен.

0 голосов
/ 11 июня 2018

Вы можете написать это так:

[TestFixture]
[Category(TestCategory.Integration)]
public class ControllersResolutionTest
{
    [Test]
    public void VerifyControllers()
    {
        var builder = new WebHostBuilder()
            .UseStartup<IntegrationTestsStartup>();
        var testServer = new TestServer(builder);
        var controllersAssembly = typeof(UsersController).Assembly;
        var controllers = controllersAssembly.ExportedTypes.Where(x => typeof(Controller).IsAssignableFrom(x));
        var activator = testServer.Host.Services.GetService<IControllerActivator>();
        var serviceProvider = testServer.Host.Services.GetService<IServiceProvider>();
        var errors = new Dictionary<Type, Exception>();
        foreach (var controllerType in controllers)
        {
            try
            {
                var actionContext = new ActionContext(
                    new DefaultHttpContext
                    {
                        RequestServices = serviceProvider
                    },
                    new RouteData(),
                    new ControllerActionDescriptor
                    {
                        ControllerTypeInfo = controllerType.GetTypeInfo()
                    });
                activator.Create(new ControllerContext(actionContext));
            }
            catch (Exception e)
            {
                errors.Add(controllerType, e);
            }
        }

        if (errors.Any())
        {
            Assert.Fail(
                string.Join(
                    Environment.NewLine,
                    errors.Select(x => $"Failed to resolve controller {x.Key.Name} due to {x.Value.ToString()}")));
        }
    }
}

Этот код на самом деле проходит полный процесс настройки основного приложения asp.net с настройкой базы данных и тем, чего у вас нет при запуске, так что вы можете захотетьизвлечь из него и удалить / посмеяться некоторые вещи.Также для этого кода требуется Microsoft.AspNetCore.TestHost nuget.


Я изменил исходный код, который был задан, так как он не работал должным образом.

...