在我的集成测试中,我使用的是我正在测试的Web API项目中构建的相同的SimpleInjector.Container.
但是组合根类中的这一行:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
导致异常:
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
评论后,一切正常,网络应用程序本身和测试.
所以问题是:
>例外的原因是什么?
>(这种方法真的需要吗?)
这是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; } }
解决方法
如果我们仔细观察堆栈跟踪,我们可以准确地看到这里发生了什么. RegisterWebApiControllers扩展方法在从HttpConfiguration获取的IHttpControllerTypeResolver实例上调用GetControllerTypes方法,并传递也从配置中检索的IAssembliesResolver.调用GetControllerTypes方法(WebHostHttpControllerTypeResolver)调用DefaultHttpControllerTypeResolver的GetControllerTypes,最终将调用System.Web.Compilation.BuildManager类的GetReferencedAssemblies.
但是,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(); }
你不得不处理这个问题有点不幸,特别是因为Simple Injector的设计是可测试的.我们似乎忽略了这一点,将RegisterWebApiControllers扩展方法与Web API深深地集成在一起.我们必须退后一步,思考如何更轻松地验证单元测试中的Web API配置.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。