В эти дни я столкнулся с проблемой с модульным тестированием Team System. Я обнаружил, что автоматически созданный класс доступа игнорирует общие ограничения - по крайней мере, в следующем случае:
Предположим, у вас есть следующий класс:
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
Похоже на ошибку. Обходной путь - изменить метод на internal и добавить [assembly: InternalsVisibleTo("MyLibrary.Test")] в сборку, содержащую тестируемый класс.
Это был бы мой предпочтительный способ тестирования закрытых методов, так как он дает гораздо более чистые модульные тесты.
«Закрыто, так как не исправить»? Фантастика.