Почему атрибут ClassCleanup должен находиться в статическом методе?

Предыстория: у меня есть куча модульных тестов в .NET, для запуска которых требуется настроить некоторые данные конфигурации. Первоначально я использовал TestInitialize и TestCleanup для установки и удаления данных конфигурации для каждого теста; однако для всего набора тестов достаточно одной настройки, поэтому вместо этого я бы предпочел использовать ClassInitialize и ClassCleanup.

Проблема: когда я меняю атрибут с TestInitialize на ClassInitialize и запускаю тесты, я получаю следующую ошибку:

MyTestClass.ClassInit имеет неправильную подпись. Метод должен быть помечен как статический.

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

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


person user1968292    schedule 01.10.2013    source источник
comment
можете показать код декорированного метода [ClassInitialize]? это должно быть похоже на public static void MethodName(TestContext context) в VB.Net Public Shared Sub MethodName(ByVal testContext As TestContext)   -  person Damith    schedule 01.10.2013
comment
Я знаю, что он должен быть статичным; сообщение об ошибке достаточно ясно. Мой вопрос в том, почему это не может быть метод экземпляра.   -  person user1968292    schedule 01.10.2013


Ответы (1)


Как указано в MSDN, ClassInitializeAttribute

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

один пример, о котором я могу подумать, где это может пригодиться, - это когда у вас есть статическое поле в вашем классе, от которого зависит конструктор экземпляров.

class foo
{
  static someObject bar;
  int foobar;

  public foo()
  {
    this.foobar = foo.bar.SomeMethod()
  }
}

таким образом, в вашем методе ClassInitializeAttribute вы можете присвоить значение статическому объекту bar, что повлияет на все экземпляры, созданные позже.

Другой случай, когда вы можете захотеть использовать ClassInitializeAttribute, — это назначение глобальных объектов, которые может использовать тест (например, mock база данных и т. д.)

person Avi Turner    schedule 01.10.2013
comment
Звучит разумно. Спасибо, что нашли время ответить! - person user1968292; 01.10.2013