5

내 통합 테스트에서 테스트중인 웹 API 프로젝트에서 생성하는 것과 동일한 SimpleInjector.Container를 사용하고 있습니다.container.RegisterWebApiControllers (GlobalConfiguration.Configuration)에 의해 InvalidOperationException이 발생합니다.

는하지만 구성 루트 클래스에서이 라인 : 모든 것이 잘 작동을 주석 한 후 웹 응용 프로그램 자체와 테스트를 모두

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 

:

container.RegisterWebApiControllers(GlobalConfiguration.Configuration); 

는 예외가 발생합니다.

그래서 질문은 :

  • 제외에 대한 이유는 무엇입니까?
  • (그리고이 방법은 정말 필요합니까?)

여기 HttpClientFactory의 코드 (예 : API 키 또는 허가 등의 적절한 헤더와 HttpClient를를 제작하는 헬퍼 클래스)입니다 :

internal static class HttpClientFactory 
{ 
    private static readonly Container _container = ContainerConfig.CreateWebApiContainer(); 

    public static HttpClient Create() 
    { 
     var client = new HttpClient { BaseAddress = GetUrl() }; 
     //... 
     return client; 
    } 
} 
+1

InnerException 및 StackTrace 세부 정보를 게시 할 수 있습니까? 설정 파일에 바인딩 리디렉션이 있습니까? –

+1

@DarinDimitrov에 동의합니다. 전체 스택 추적을주세요. 이러한 세부 사항이 없으면이를 추론하기가 어렵습니다. – Steven

+0

@ 다린 : 업데이트되었습니다. 감사합니다! 바인드 리디렉션은 Web.config에있는 것과 매우 유사합니다. – abatishchev

답변

5

하는 경우 스택 추적을 면밀히 살펴보면서 여기서 무슨 일이 벌어지고 있는지 정확하게 볼 수 있습니다. RegisterWebApiControllers 확장 메서드는 IHttpControllerTypeResolver 인스턴스에서 HttpConfiguration에서 가져 오는 GetControllerTypes 메서드를 호출하고 구성에서 검색 한 IAssembliesResolver을 전달합니다. 호출 된 GetControllerTypes 메서드 (WebHostHttpControllerTypeResolver)는 DefaultHttpControllerTypeResolverGetControllerTypes을 호출하며 결국 System.Web.Compilation.BuildManager 클래스의 GetReferencedAssemblies이 호출됩니다.

그러나 System.Web.Compilation.BuildManager은 ASP.NET 파이프 라인에서 일찍 호출하거나 ASP.NET 컨텍스트 외부에서 호출 할 수 없습니다. 테스트 중이므로 BuildManage은 발생하는 예외를 throw합니다.

단위 테스트를 할 때 솔루션 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(); 
} 

그것은 간단한 인젝터를 테스트 할 수 있도록 설계되었다 특히 이후,이 거래를해야한다는 조금 불행한 일입니다. RegisterWebApiControllers 확장 방법을 웹 API와 너무 깊이 통합하여 간과 한 것 같습니다. 우리는 한 걸음 물러서서 단위 테스트 내부에서 Web API 구성을보다 쉽게 ​​검증하는 방법에 대해 생각해야합니다.

+0

안녕하세요, 스티븐, 최근 웹 API 통합 패키지의 새 버전을 출시했지만이 문제는 아직 해결되지 않았습니다. – abatishchev

+0

@abatishchev : 맞습니다. v2.6.2 웹 API 통합 패키지는 문제 상태 [여기] (https://simpleinjector.codeplex.com/workitem/20987) 만 수정합니다. 지금 당장은 내 답변에 설명 된 해결 방법을 수행하거나 'RegisterWebApiControllers'를 호출하는 대신 사용자 정의 컨트롤러 등록을 작성해야합니다. – Steven

+0

안녕하세요, 스티븐,이 문제를 해결하기위한 뉴스/계획이 있으십니까? – abatishchev

3

SI의 V3.0의에 대한 해결책은 그래서 지금은 컨트롤러를 검색 할 어셈블리를 알고 .. 그냥 ...

container.RegisterWebApiControllers(
    GlobalConfiguration.Configuration, 
    Assembly.GetExecutingAssembly() 
); 

입니다.

관련 문제