专用访问器类忽略通用约束
时间:2020-03-05 18:54:00 来源:igfitidea点击:
这些天,我遇到了团队系统单元测试的问题。我发现自动创建的访问器类至少在以下情况下会忽略通用约束:
假设我们有以下课程:
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(".ctor@0")] public MyClass_Accessor(); public MyClass_Accessor(PrivateObject __p1); public static PrivateType ShadowedType { get; } public static MyClass_Accessor AttachShadow(object __p1); [Shadowing("MyMethod@1")] public T? MyMethod(string s); } }
如我们所见,MyMethod方法的泛型类型参数没有任何约束。
那是个错误吗?这是设计使然吗?谁知道如何解决该问题?
解决方案
回答
我投票给臭虫。我不知道这是怎么设计的。
回答
我没有验证所有内容,但看起来像是调用:
TestEnum? e1 = target.MyMethod("item2");
使用类型推断来确定泛型类型参数T。如果可能,尝试在测试中以其他方式调用该方法:
TestEnum? e1 = target.MyMethod<TestEnum>("item2");
这可能会产生不同的结果。
希望对我们有所帮助!
回答
在msdn上搜索具有泛型的单元测试。这是一个已知的限制。绝对需要解决Microsoft Connect上的解决方案。
回答
这是连接上的类似问题,以供参考。
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324473&wa=wsignin1.0
回答
看起来像个虫子。解决方法是将方法更改为"内部",并将" [assembly:InternalsVisibleTo(" MyLibrary.Test")]]`添加到包含被测类的程序集。
这将是我首选的测试非公开方法的方法,因为它会产生看起来更简洁的单元测试。