如何在 Owin TestServer 创建后更新 HttpConfiguration
How to Update the HttpConfiguration AFTER the Owin TestServer creation
http 配置在 te Startup class 中设置,通常绑定到 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);
目前我不得不为每个测试方法创建一个 TestServer。
这是时间上的总开销。
解决方案
将 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 服务器。
- 为您的所有测试声明基础 class classes
- 在 OWIN 服务器的基础 class 中声明一个私有静态只读变量。
private static readonly TestServer _webServer = TestServer.Create<Startup>();
- 声明一个受保护的静态变量以将此服务器暴露给所有测试。
protected static TestServer WebServer { get { return _webServer; } }
这应该可以解决您在所有测试运行中仅实例化 Web 服务器一次的问题。如果你不想这么早初始化网络服务器,你可以使用惰性实例化等。但关键是让它成为静态的并在定义时本身初始化它,这样每个应用程序域就一次。
至于在单元测试中访问 HttpConfiguration.. 这是一种可能的方法..
- 在你的 Startup.cs 中声明一个 public 属性...
public static HttpConfiguration HttpConfiguration { get; private set; }
在Startup.csclass.
的configure方法中初始化这个变量
HttpConfiguration = new HttpConfiguration();
HttpConfiguration.MapHttpAttributeRoutes();
// do more stuff.. setting resolver etc.
// and then finally
app.UseWebApi(HttpConfiguration);
此 HttpConfiguration 属性 是您的网站 api 的配置,因为我们将其设为 public 属性,它应该可以在您的测试项目和所有测试。
Startup.HttpConfiguration
您可以访问它来修改依赖解析器定义等
Startup.HttpConfiguration.DependencyResolver
请注意,即使在初始化 Web 服务器之后,您也可以更新 DependencyResolver 定义...更新后的定义仍然有效。
- 如果您担心您的 HttpConfiguration 仅 public 可用,则将 Startup class 设为内部并使其仅对您的单元测试项目可见。
http 配置在 te Startup class 中设置,通常绑定到 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);
目前我不得不为每个测试方法创建一个 TestServer。
这是时间上的总开销。
解决方案
将 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 服务器。
- 为您的所有测试声明基础 class classes
- 在 OWIN 服务器的基础 class 中声明一个私有静态只读变量。
private static readonly TestServer _webServer = TestServer.Create<Startup>();
- 声明一个受保护的静态变量以将此服务器暴露给所有测试。
protected static TestServer WebServer { get { return _webServer; } }
这应该可以解决您在所有测试运行中仅实例化 Web 服务器一次的问题。如果你不想这么早初始化网络服务器,你可以使用惰性实例化等。但关键是让它成为静态的并在定义时本身初始化它,这样每个应用程序域就一次。
至于在单元测试中访问 HttpConfiguration.. 这是一种可能的方法..
- 在你的 Startup.cs 中声明一个 public 属性...
public static HttpConfiguration HttpConfiguration { get; private set; }
在Startup.csclass.
的configure方法中初始化这个变量HttpConfiguration = new HttpConfiguration(); HttpConfiguration.MapHttpAttributeRoutes(); // do more stuff.. setting resolver etc. // and then finally app.UseWebApi(HttpConfiguration);
此 HttpConfiguration 属性 是您的网站 api 的配置,因为我们将其设为 public 属性,它应该可以在您的测试项目和所有测试。
Startup.HttpConfiguration
您可以访问它来修改依赖解析器定义等
Startup.HttpConfiguration.DependencyResolver
请注意,即使在初始化 Web 服务器之后,您也可以更新 DependencyResolver 定义...更新后的定义仍然有效。
- 如果您担心您的 HttpConfiguration 仅 public 可用,则将 Startup class 设为内部并使其仅对您的单元测试项目可见。