2016-06-28 7 views
1

간단한 단위 테스트 패턴을 설계하고 moq 라이브러리를 사용했습니다. 그러나 Container.Resolve<IInterface>() 메서드를 실행할 때 예외가 발생합니다.구성 요소 후기 바인딩에 커미션 문제를 적용 할 수 없으므로 대상 없음 프록시로 나타납니다. 현재 지원되지 않습니다.

container.Register(Component.For<TBase>().UsingFactoryMethod(() => 
{ 
    var mockObject = new Mock<TBase>(); 
    var mockType = typeof(TBase); 

    if (container is Core.IoCContainer.IoCCore.CustomContainer) 
    { 
     var resolvingDelege = (container as Core.IoCContainer.IoCCore.CustomContainer).ResolvingTestDelegateList[mockType]; 

     if (resolvingDelege != null) 
     { 
      resolvingDelege(mockType, mockObject); 
     } 
    } 

    return mockObject.Object; 
}) 
.LifestyleTransient()); 

IoCCore.Container.Resolve< ISampleDataContext>(); 실행 중이 예외가 발생되고 다음은 성 윈저에 대한 등록 방법이다. 예외 메시지는 "구성 요소 후기 바인딩 된 Data.Context.ISampleDataContext에 커미션 문제를 적용 할 수 없습니다. 대상이없는 프록시로 보이므로 현재 지원되지 않습니다."

문제를 검색 한 결과 mockObject.ObjectCastle.DynamicProxy.IProxyTargetAccessor 인 것을 발견했습니다. 따라서, Castle.MicroKernel.ComponentActivator.AbstractComponentActivator 클래스 아래 다음의 코드를 예를 해결하는 동안 문제가 발생하는 곳이다

protected virtual void ApplyCommissionConcerns(object instance) 
    { 
     if (Model.Lifecycle.HasCommissionConcerns == false) 
     { 
      return; 
     } 

     instance = ProxyUtil.GetUnproxiedInstance(instance); 
     if (instance == null) 
     { 
      // see http://issues.castleproject.org/issue/IOC-332 for details 
      throw new NotSupportedException(string.Format("Can not apply commission concerns to component {0} because it appears to be a target-less proxy. Currently those are not supported.", Model.Name)); 
     } 
     ApplyConcerns(Model.Lifecycle.CommissionConcerns, instance); 
    } 

UsingFactoryMethod 의해 해결되는 오브젝트 모의 객체가 생성 Castle.DynamicProxy.IProxyTargetAccessor이다. 그러나 Castle Windsor는 IProxyTargetAccessor이 mock 객체 대신에 자체적으로 생성된다고 가정합니다. 이로 인해 CommissionConcerns의 빈 인스턴스가 내 모의 인스턴스에서 반환됩니다.

이 버그의 가능한 회피 방법이 있습니까? 업데이트를 기다려야합니까?

답변

0

이 문제의 해결 방법을 마련했습니다. 아래 코드 대신 UseFactoryMethod 메서드를 변경했습니다.

Component.For<TBase>().UsingFactoryMethod(() => 
      { 
       var mockObject = new Mock<TBase>(); 
       var mockType = typeof(TBase); 

       if (container is Core.IoCContainer.IoCCore.CustomContainer) 
       { 
        var resolvingDelege = (container as Core.IoCContainer.IoCCore.CustomContainer).ResolvingTestDelegateList[mockType]; 

        if (resolvingDelege != null) 
        { 
         resolvingDelege(mockType, mockObject); 
        } 
       } 

       //The code that was changed 
       //============================================== 
       var type = mockObject.Object.GetType(); 
       var field = type.GetField("__target"); 

       field.SetValue(mockObject.Object, new Object()); 
       //============================================== 

       return mockObject.Object; 
      }) 
      .LifestyleTransient());