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

В эти дни я столкнулся с проблемой с модульным тестированием 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.

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
4 464
5

Ответы 5

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

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

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

«Закрыто, так как не исправить»? Фантастика.

Tullo_x86 24.08.2010 04:43

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

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

Другие вопросы по теме