Класс Private Accessor игнорирует общее ограничение

На днях я столкнулся с проблемой Team System Unit Testing. Я обнаружил, что автоматически созданный класс доступа игнорирует общие ограничения — по крайней мере, в следующем случае:

Предположим, у вас есть следующий класс:

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 нет.

Это ошибка? Это по дизайну? Кто знает как обойти эту проблему?


person JRoppert    schedule 15.09.2008    source источник


Ответы (5)


Я голосую за ошибку. Я не понимаю, как это может быть задумано.

person Community    schedule 15.09.2008

Вот аналогичная проблема с подключением для справки. https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324473&wa=wsignin1.0

person Josh Heyse    schedule 28.07.2009
comment
Закрыто как не исправится? Фантастический. - person Tullo_x86; 24.08.2010

Я не проверял все, но это похоже на вызов:

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

использует вывод типа для определения параметра универсального типа T. Попробуйте вызвать метод по-другому в тесте, если это возможно:

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

Это может дать разные результаты.

Надеюсь, это поможет!

person Zachary Yates    schedule 03.10.2008

Похоже на ошибку. Обходным путем может быть изменение метода на internal и добавление [assembly: InternalsVisibleTo("MyLibrary.Test")] в сборку, содержащую тестируемый класс.

Это был бы мой предпочтительный способ тестирования непубличных методов, поскольку он производит гораздо более чистые модульные тесты.

person Igor Zevaka    schedule 25.08.2010

Найдите модульные тесты с дженериками в msdn. Это известное ограничение. Проголосуйте за решение на Microsoft Connect, так как оно определенно нуждается в разрешении.

person Community    schedule 20.10.2008