Класс Private Accessor игнорирует общие ограничения - PullRequest
4 голосов
/ 15 сентября 2008

В эти дни у меня возникла проблема с групповым тестированием системы. Я обнаружил, что автоматически созданный класс средства доступа игнорирует общие ограничения - по крайней мере, в следующем случае:

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

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.

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

Ответы [ 5 ]

3 голосов
/ 15 сентября 2008

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

2 голосов
/ 28 июля 2009

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

1 голос
/ 26 августа 2010

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

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

1 голос
/ 03 октября 2008

Я не все проверил, но похоже на звонок:

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

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

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

Это может привести к разным результатам.

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

0 голосов
/ 20 октября 2008

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

...