2014-09-19 2 views
1

속성 유형이이고 인터페이스가 PropertyInfo.SetValue 인 경우 클래스의 속성 값을 설정하는 데 문제가 있습니다. 이 코드는 단위 테스트 용으로, 내 엔터티에서 IDbSets를 가짜로 만들 때 사용하고 싶습니다.리플렉션을 사용하여 인터페이스 멤버 설정

Object of type 'lnEcommAPI.Tests.FakeDbSet 1[System.Data.Entity.IDbSet 1[LNWebServicesRepository.WhatsNew]]' cannot be converted to type 'System.Data.Entity.IDbSet`1[LNWebServicesRepository.WhatsNew]'.

+0

을 기대하는 동안 따라서, typeof(FakeDbSet<>).MakeGenericType(iDbSet.PropertyType)FakeDbSet<IDbSet<XXX>>을 만듭니다. –

답변

1

내 생각 :

var genericType = baseType.MakeGenericType(iDbSet.PropertyType.GetGenericArguments()[0]); 

문제가에 의해

var genericType = baseType.MakeGenericType(iDbSet.PropertyType); 

을 대체

public static void AddFakeDbSets<T>(this Mock<T> obj) where T : class 
{ 
    var iDbSets = typeof(T).GetProperties().Where(p => 
     p.PropertyType.IsGenericType == true && 
     p.PropertyType.GetGenericTypeDefinition().Name.StartsWith("IDbSet")); 

    Type baseType = typeof(FakeDbSet<>); 

    foreach (var iDbSet in iDbSets) 
    { 
     if (iDbSet.GetValue(obj.Object) == null) 
     { 
      var genericType = baseType.MakeGenericType(iDbSet.PropertyType); 
      var concreteObject = Activator.CreateInstance(genericType); 
      iDbSet.SetValue(obj.Object, concreteObject); 
     } 
    } 
} 

은 특히 다음과 같은 오류 iDbSet.SetValue()에 충돌 그 iDbSet.PropertyTypeIDbSet<XXX>과 같습니다. 답변 충돌을 수정하지만 MOQ는 여전히 값을 할당하는 방법으로 가져옵니다 당신이 미래의 독자들에게 FakeDbSet<XXX>

+0

탁월한 캐치, 더 이상 충돌하지 않지만 속성이 설정되지 않습니다. 헤드 스크래쳐 (head scratcher)의 종류, 나는 그것이 Moq과 관련이 있다고 생각하고 있었지만, 그것은 문제가되어서는 안된다. –

+0

이 경우 동일한 문제가 아닙니다! – Olivier

+0

속성 setter가 비어있을 수 있습니다 ... iDbSet.GetGetMethod(). GetMethodBody(). GetILAsByteArray(). Length ... 길이가 4 바이트보다 짧으면 설정자가 아무것도 수행하지 않습니다. – Olivier

관련 문제