如何在创建 Owin TestServer 后更新 httpConfiguration

本文关键字:更新 httpConfiguration TestServer Owin 创建 | 更新日期: 2023-09-27 17:56:51

http配置通常在绑定到Create方法的Startup class中设置。

但是,如果我想为所有测试启动一次 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);

如何在创建 Owin TestServer 后更新 httpConfiguration

如果要为所有测试启动一次 OWIN 服务器。

  1. 为所有测试类声明基类
  2. 在 OWIN 服务器的基类中声明一个私有静态只读变量。

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

  1. 声明一个受保护的静态变量,以向所有测试公开此服务器。

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

这应该可以解决所有测试运行仅实例化一次 Web 服务器的问题。 如果你不想这么早初始化 Web 服务器,你可以使用延迟实例化等,但重点是让它静态并在定义时初始化它本身,以便每个应用程序域一次。

至于在你的单元测试中访问HttpConfiguration..这是一种可能的方法..

  1. 在您的 Startup.cs 中,声明一个公共属性...

public static HttpConfiguration HttpConfiguration { get; private set; }

  1. 在 Startup.cs 类的配置方法中初始化此变量。

        HttpConfiguration = new HttpConfiguration();
        HttpConfiguration.MapHttpAttributeRoutes();
        // do more stuff.. setting resolver etc.
        // and then finally
        app.UseWebApi(HttpConfiguration);
    
  2. 此 HttpConfiguration 属性是 Web API 的配置,由于我们将其设置为公共属性,因此应在测试项目和所有测试中访问它。

        Startup.HttpConfiguration
    

您可以访问它以修改依赖项解析程序定义等。

        Startup.HttpConfiguration.DependencyResolver

请注意,即使在初始化 Web 服务器后,您也可以更新依赖项解析程序定义...更新后的定义仍将具有效力。

  1. 如果您担心 HttpConfiguration 只是公开可用,请将 Startup 类设置为内部,并使其仅对单元测试项目可见。