2008-09-15 12 views
4

最近、私はチームシステムユニットテストの問題に遭遇しました。私は自動的に作成されたアクセサクラスは、一般的な制約を無視することがわかった - 少なくとも、次の場合には:プライベートアクセサクラスはジェネリック制約を無視します

あなたは以下のクラスがあるとします。

namespace MyLibrary 
{ 
public class MyClass 
{ 
    public Nullable<T> MyMethod<T>(string s) where T : struct 
    { 
    return (T)Enum.Parse(typeof(T), s, true); 
    } 
} 
} 

あなたがMyMethodはをテストしたい場合は、テストプロジェクトを作成することができます

public enum TestEnum { Item1, Item2, Item3 } 

[TestMethod()] 
public void MyMethodTest() 
{ 
MyClass c = new MyClass(); 
PrivateObject po = new PrivateObject(c); 
MyClass_Accessor target = new MyClass_Accessor(po); 

// The following line produces the following error: 
// Unit Test Adapter threw exception: GenericArguments[0], 'T', on 
// 'System.Nullable`1[T]' violates the constraint of type parameter 'T'.. 
TestEnum? e1 = target.MyMethod<TestEnum>("item2"); 

// The following line works great but does not work for testing private methods. 
TestEnum? e2 = c.MyMethod<TestEnum>("item2"); 
} 

上記のスニペットのコメントに記載されているエラーでテストを実行すると失敗します。問題は、Visual Studioで作成されたアクセサークラスです。あなたがそこに行けば、あなたは以下のコードに出てくる:あなたが見ることができるように

namespace MyLibrary 
{ 
[Shadowing("MyLibrary.MyClass")] 
public class MyClass_Accessor : BaseShadow 
{ 
    protected static PrivateType m_privateType; 

    [Shadowing("[email protected]")] 
    public MyClass_Accessor(); 
    public MyClass_Accessor(PrivateObject __p1); 
    public static PrivateType ShadowedType { get; } 
    public static MyClass_Accessor AttachShadow(object __p1); 

    [Shadowing("[email protected]")] 
    public T? MyMethod(string s); 
} 
} 

、MyMethodはメソッドのジェネリック型パラメータには制約がありません。

これはバグですか?それは設計によるのですか?誰がその問題を回避する方法を知っていますか?

答えて

3

私はバグに投票しました。私はこれがどのように設計されているのか分かりません。

1

私はすべてを検証しませんでしたが、それはへの呼び出しのようになります。

TestEnum? e1 = target.MyMethod("item2"); 

は、ジェネリック型のparam T.が可能であれば、テストで異なるメソッドを呼び出してみ決定するために型推論を使用しています。

TestEnum? e1 = target.MyMethod<TestEnum>("item2"); 

異なる結果が生じることがあります。

希望に役立ちます!

0

msdnでジェネリックでユニットテストを検索します。これは既知の制限です。確かに解決が必要なので、Microsoft Connectの解決に投票してください。

1

バグのようです。回避策は、メソッドをinternalに変更し、テスト対象のクラスを含むアセンブリに[assembly: InternalsVisibleTo("MyLibrary.Test")]を追加することです。

これは、よりパワフルな見た目の単体テストを生成するので、非公開メソッドをテストする私の好ましい方法です。

関連する問題