2016-03-20 12 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この:ここでは、テスト対象システムのWhere句は私の他のアセンブリから正しい性質をつかむしないので

[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); 
    } 
} 

はしかし、これは、動作しません。私のテストは、単一のプロパティをテストしないので失敗します。


未遂修正なし1

私はこのようなthis answer試してみた:

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

をしかし、それは唯一のItem.ICollectionPropをキャッチし、他のすべてのテストに失敗しました。修正なし2

第二にしようとしました


、私は(GetICollectionOrICollectionOfTProperties方法広告そのままを使用して)this answer to another questionを試してみた、このような:間違って渡します

var collectionProps = type 
    .GetICollectionOrICollectionOfTProperties(); 

しかし皮肉なことに、 Item.ICollectionPropがインスタンス化されていなくてもテスト。 、

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

しかしstringIEnumerableあるので、それは、Item.StringPropに失敗します:しようとしました


はこのように、単にすべてのIEnumerableプロパティなし3

私も試してみたテストを修正しません私はここでそれをテストしたくありません。


私が間違って行くところ私はのみ動作するソリューションを得ていたと思います場合は特に、NR 2で、私も、私の質問は、その1の複製であると思うだろう、よく分かりません。

ボトムライン:(X)クラスがインスタンス化されたときに空のコンストラクタを持つクラスのすべてのコレクションプロパティがインスタンス化されることをテストする方法、および/または(Y)リフレクトを使用してタイプのすべてのコレクションプロパティを見つける方法を教えてください。

私は何とかICollectionまたはICollection<>に基づいているすべてのタイプを見つけるために、このヘルパー関数を使用することをお勧め

答えて

1

:あなたのテストで

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)); 
関連する問題