2016-03-20 40 views
0

我想製作一個單元測試,將檢查給定的程序集,所有具有空構造函數的非抽象類將在實例化時實例化它們的集合屬性。這裏的被測系統:使用反射來測試類的所有集合屬性將被實例化

namespace MyProject.Dto.Things 
{ 
    public class Item 
    { 
     public Item() 
     { 
      // Second batch of props should be instantiated here... 
     } 

     // Properties that my test doesn't/shouldn't care about: 
     public int IntProp { get; set; } 
     public string StringProp { get; set; } 

     // Properties my test should account for: 
     public List<string> ListProp { get; set; } 
     public IList<string> IListProp { get; set; } 
     public ISet<string> ISetProp { get; set; } 
     public ICollection<string> ICollectionProp { get; set; } 
     public IDictionary<string, string> IDictionaryProp { get; set; } 
     public Stack<string> StackProp { get; set; } 
     public string[] ArrayProp { get; set; } 
    } 
} 

我第一次嘗試whas這樣的:

[TestFixture] 
public class DtoTests 
{ 
    [Test] 
    public void NamespaceDtos_WhenDefaultConstructorIsCalled_InstantiatesCollectionProperties() 
    { 
     bool testWasMeaningful = false; 

     foreach (var type in GetEntityTypesWithDefaultConstructor()) 
     { 
      var instance = Activator.CreateInstance(type); 
      var collectionProps = type 
       .GetProperties() 
       .Where(p => typeof(ICollection<>).IsAssignableFrom(p.PropertyType)); 

      foreach (var prop in collectionProps) 
      { 
       var val = prop.GetValue(instance); 
       Assert.That(val, Is.Not.Null.And.Empty, string.Format("[{0}.{1}]", type.Name, prop.Name)); 
       testWasMeaningful = true; 
      } 
     } 

     Assert.That(testWasMeaningful, "Expected at least one assertion."); 
    } 

    private IEnumerable<Type> GetEntityTypesWithDefaultConstructor() 
    { 
     return Assembly 
      .GetAssembly(typeof(MyProject.Dto.Things.Item)) 
      .GetTypes() 
      .Where(t => !t.IsAbstract) 
      .Where(t => t.GetConstructor(Type.EmptyTypes) != null); 
    } 
} 

然而,這不起作用,因爲Where條款搶不從我的其他組件正確的屬性。我的測試失敗,因爲它沒有測試一個屬性。


試圖修復沒有1

我已經試過this answer這樣的:

var collectionProps = type 
    .GetProperties() 
    .Where(m => m.PropertyType.IsGenericType && m.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>)); 

但這隻能捕獲Item.ICollectionProp,並沒有測試所有其他人。


試圖修復不2

其次,我已經試過this answer to another question(使用GetICollectionOrICollectionOfTProperties方法廣告逐字),像這樣:

var collectionProps = type 
    .GetICollectionOrICollectionOfTProperties(); 

但諷刺的是,這將傳遞錯誤測試即使Item.ICollectionProp沒有實例化。


試圖修復3號

我還試圖測試只是所有IEnumerable屬性,像這樣:

var collectionProps = type 
    .GetProperties() 
    .Where(p => typeof(IEnumerable).IsAssignableFrom(p.PropertyType)); 

但是,這都將失敗Item.StringProp,因爲stringIEnumerable,我不想在這裏測試。


我不知道我走到哪裏錯了,尤其是NR 2。我甚至會想,我的問題是一個重複的,如果我只已經得到解決工作。 (X)如何測試當實例化類時實例化具有空構造函數的類的所有集合屬性,和/或(Y)如何使用反射找到所有類型的集合屬性?

回答

1

我建議使用這個輔助函數來查找在某種程度上基於ICollectionICollection<>所有類型:

private static bool IsOrImplementsICollection(Type t) 
{ 
    if (t == typeof (ICollection) || (t.IsGenericType && t.GetGenericTypeDefinition() == typeof (ICollection<>))) 
     return true; 
    return t.GetInterfaces().Any(IsOrImplementsICollection); 
} 

在您的測試,那麼你可以改變where子句:

var collectionProps = type 
    .GetProperties() 
    .Where(x => IsOrImplementsICollection(x.PropertyType)); 
相關問題