aba*_*hev 7 c# dependency-injection simple-injector asp.net-web-api
在我的集成测试中,我使用的是我正在测试的Web API项目中构建的相同的SimpleInjector.Container.
但是组合根类中的这一行:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
Run Code Online (Sandbox Code Playgroud)
导致异常:
System.TypeInitializationException : The type initializer for 'MyProject.Api.Test.Integration.HttpClientFactory' threw an exception.
---- System.InvalidOperationException : This method cannot be called during the application's pre-start initialization phase.
Result StackTrace:
at MyProject.Api.Test.Integration.HttpClientFactory.Create()
at MyProject.Api.Test.Integration.Controllers.ProductControllerIntegrationTest.<GetProductBarcode_Should_Return_Status_BadRequest_When_Barcode_Is_Empty>d__0.MoveNext() in d:\Projects\My\MyProject.Api.Test.Integration\Controllers\ProductControllerIntegrationTest.cs:line 26
----- Inner Stack Trace -----
at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
at System.Web.Compilation.BuildManager.GetReferencedAssemblies()
at System.Web.Http.WebHost.WebHostAssembliesResolver.System.Web.Http.Dispatcher.IAssembliesResolver.GetAssemblies()
at System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at System.Web.Http.WebHost.WebHostHttpControllerTypeResolver.GetControllerTypes(IAssembliesResolver assembliesResolver)
at SimpleInjector.SimpleInjectorWebApiExtensions.GetControllerTypesFromConfiguration(HttpConfiguration configuration)
at SimpleInjector.SimpleInjectorWebApiExtensions.RegisterWebApiControllers(Container container, HttpConfiguration configuration)
at MyProject.Api.ContainerConfig.RegisterTypes(Container container) in d:\Projects\My\MyProject.Api\App_Start\ContainerConfig.cs:line 128
at MyProject.Api.ContainerConfig.CreateWebApiContainer() in d:\Projects\My\MyProject.Api\App_Start\ContainerConfig.cs:line 63
at MyProject.Api.Test.Integration.HttpClientFactory..cctor() in d:\Projects\My\MyProject.Api.Test.Integration\HttpClientFactory.cs:line 17
Run Code Online (Sandbox Code Playgroud)
评论后,一切正常,网络应用程序本身和测试.
所以问题是:
这是HttpClientFactory的代码(一个辅助类,用于创建具有适当头的HttpClient,例如api密钥或授权):
internal static class HttpClientFactory
{
private static readonly Container _container = ContainerConfig.CreateWebApiContainer();
public static HttpClient Create()
{
var client = new HttpClient { BaseAddress = GetUrl() };
//...
return client;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我们仔细观察堆栈跟踪,我们可以准确地看到这里发生了什么.该RegisterWebApiControllers扩展方法调用GetControllerTypes的方法IHttpControllerTypeResolver其从抓住实例HttpConfiguration,并将其传递的IAssembliesResolver,其也从配置检索.被叫GetControllerTypes(方法WebHostHttpControllerTypeResolver)调用到GetControllerTypes了的DefaultHttpControllerTypeResolver,这将最终导致调用GetReferencedAssemblies了的System.Web.Compilation.BuildManager类.
该System.Web.Compilation.BuildManager然而,不能在ASP.NET管道叫早,或ASP.NET的所有范围之外.由于您BuildManage正在进行测试,因此会抛出您遇到的异常.
因此,这里的解决方案(或"技巧")将IAssembliesResolver在单元测试时替换默认值.我认为旋转变压器看起来像这样:
public class TestAssembliesResolver : IAssembliesResolver
{
public ICollection<Assembly> GetAssemblies()
{
return AppDomain.CurrentDomain.GetAssemblies();
}
}
[TestMethod]
public void TestMethod1()
{
// Replace the original IAssembliesResolver.
GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver),
new TestAssembliesResolver());
var container = SimpleInjectorWebApiInitializer.BuildContainer();
container.Verify();
}
Run Code Online (Sandbox Code Playgroud)
你不得不处理这个问题有点不幸,特别是因为Simple Injector的设计是可测试的.我们似乎通过将RegisterWebApiControllers扩展方法与Web API深入集成来忽略这一点.我们必须退后一步,思考如何更轻松地验证单元测试中的Web API配置.
| 归档时间: |
|
| 查看次数: |
3035 次 |
| 最近记录: |