Как обновить HttpConfiguration ПОСЛЕ создания Owin TestServer

Конфигурация http настраивается в классе Startup, который обычно связан с методом Create.

Но что, если я хочу запустить сервер owin ОДИН время для ВСЕХ тестов, но обновить его конфигурацию http в зависимости от каждого теста?

Это невозможно. Объект сервера не имеет ничего полезного.

using (var server = TestServer.Create<Startup>())
{
    var data = server.HttpClient.GetAsync("/api/data);
}

Что я хочу сделать для тестов интеграции CRUD, это опустить методы обслуживания

// Do it ONE time fall ALL tests
WebApiConfig.Register(config);
WebServicesConfig.Register(config);

// Do it individually for each test, Update DI registerations with Fake components per test method
var builder = new ContainerBuilder();
var mockContext = new Mock<TGBContext>();
var mockService = new Mock<SchoolyearService>(mockContext.Object); 
mockService.Setup<Task<IEnumerable<SchoolyearDTO>>>(c => c.GetSchoolyearsAsync()).Returns(Task.FromResult(Enumerable.Empty<SchoolyearDTO>()));
// builder.RegisterInstance<TGBContext>(); ****** NO NEED for this it works without registering the ctor parameter dependency 
builder.RegisterInstance<SchoolyearService>(mockService.Object);
builder.Update(((AutofacWebApiDependencyResolver)config.DependencyResolver).Container as IContainer);

В настоящий момент я вынужден создать тестовый сервер для каждого тестового метода.

Это означает, что вовремя потеряны затраты.

Решение

Сделайте HttpConfiguration статическим, и этот код должен работать:

var builder = new ContainerBuilder();
var mockContext = new Mock<TGBContext>();
var mockService = new Mock<SchoolyearService>(mockContext.Object);
mockService.Setup<Task<IEnumerable<SchoolyearDTO>>>(c => c.GetSchoolyearsAsync()).Returns(Task.FromResult(Enumerable.Empty<SchoolyearDTO>()));
 builder.RegisterInstance<SchoolyearService>(mockService.Object);
builder.Update(((AutofacWebApiDependencyResolver)Configuration.DependencyResolver).Container as IContainer);

Ответ 1

если вы хотите запустить сервер OWIN один раз для всех тестов.

  • объявить базовый класс для всех ваших тестовых классов
  • объявить приватную переменную readonly в базовом классе для сервера OWIN.

private static readonly TestServer _webServer = TestServer.Create<Startup>();

  1. объявить защищенную статическую переменную, чтобы открыть этот сервер для всех тестов.

protected static TestServer WebServer { get { return _webServer; } }

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

как для получения доступа к HttpConfiguration в ваших модульных тестах.. вот один из возможных способов.

  • в вашем Startup.cs, объявите публичное свойство...

public static HttpConfiguration HttpConfiguration { get; private set; }

  1. инициализировать эту переменную в методе configure для класса Startup.cs.

        HttpConfiguration = new HttpConfiguration();
        HttpConfiguration.MapHttpAttributeRoutes();
    
        // do more stuff.. setting resolver etc.
        // and then finally
    
        app.UseWebApi(HttpConfiguration);
    
  2. Это свойство HttpConfiguration является вашей конфигурацией веб-api, и поскольку мы сделали это общедоступным, оно должно быть доступно в вашем тестовом проекте и во всех тестах.

        Startup.HttpConfiguration
    

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

        Startup.HttpConfiguration.DependencyResolver

обратите внимание, что вы можете обновлять определения DependencyResolver даже после инициализации веб-сервера... обновленные определения будут по-прежнему иметь эффект.

  1. если вы обеспокоены тем, что ваша HttpConfiguration просто общедоступна, затем сделайте класс Startup внутренним и сделайте его видимым только для вашего проекта unit test.