在我的集成测试中,我使用的是我正在测试的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;
}
}
答案 0 :(得分:6)
如果仔细观察堆栈跟踪,我们可以准确地看到这里发生了什么。 RegisterWebApiControllers
扩展方法在GetControllerTypes
上从IHttpControllerTypeResolver
获取的HttpConfiguration
实例上调用IAssembliesResolver
方法,并传递也从配置中检索到的GetControllerTypes
。被调用的WebHostHttpControllerTypeResolver
方法(GetControllerTypes
)会调用DefaultHttpControllerTypeResolver
的{{1}},最终会调用GetReferencedAssemblies
System.Web.Compilation.BuildManager
} class。
然而,System.Web.Compilation.BuildManager
不能在ASP.NET管道的早期调用,也不能在ASP.NET的上下文之外调用。由于您正在参加考试,BuildManage
会抛出您遇到的异常。
所以解决方案(或者诀窍&#39;所以你会这样做)在单元测试时替换默认的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配置。
答案 1 :(得分:3)
SI v3.x的解决方案只是......
container.RegisterWebApiControllers(
GlobalConfiguration.Configuration,
Assembly.GetExecutingAssembly()
);
..所以现在它知道要搜索控制器的程序集。