这些天,我遇到了团队系统单元测试的问题。我发现自动创建的访问器类忽略了通用约束 - 至少在以下情况下:
假设您有以下课程:
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方法的泛型类型参数没有约束。
这是一个错误吗?这是设计的吗?谁知道如何解决这个问题?
答案 0 :(得分:3)
我投票了。我不明白这是怎么设计的。
答案 1 :(得分:2)
以下是关于connect的类似问题以供参考。 https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324473&wa=wsignin1.0
答案 2 :(得分:1)
我没有验证所有内容,但看起来像是调用:
TestEnum? e1 = target.MyMethod("item2");
使用类型推断来确定泛型类型参数T.如果可能,尝试在测试中以不同方式调用方法:
TestEnum? e1 = target.MyMethod<TestEnum>("item2");
这可能会产生不同的结果。
希望有所帮助!
答案 3 :(得分:1)
看起来像个错误。解决方法是将方法更改为internal
并将[assembly: InternalsVisibleTo("MyLibrary.Test")]
添加到包含待测类的程序集中。
这将是我测试非公共方法的首选方法,因为它可以产生更清晰的单元测试。
答案 4 :(得分:0)
在msdn上搜索泛型的单元测试。这是一个已知的限制。投票支持Microsoft Connect,因为它肯定需要解决。