UnitTesting статические классы - PullRequest
20 голосов
/ 10 июня 2009

Сценарий. Язык C #, модульное тестирование с использованием инфраструктуры модульного тестирования VS2008

У меня есть статический класс со статическим конструктором и 2 методами. У меня есть 4 метода испытаний, написанных для проверки всего класса. Мой статический конструктор имеет несколько важных инициализаций.

Теперь, если я выполню все 4 модульных теста в тандеме, статический конструктор вызывается только в начале. В конце каждого теста нет такой вещи

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

Ответы [ 8 ]

39 голосов
/ 15 марта 2012
Type staticType = typeof(StaticClassName);
ConstructorInfo ci = staticType.TypeInitializer;
object[] parameters = new object[0];
ci.Invoke(null, parameters);

от http://colinmackay.scot/2007/06/16/unit-testing-a-static-class/

12 голосов
/ 10 июня 2009

Самое простое решение - добавить метод «Reset» к вашему статическому классу, который будет иметь такое же поведение, как уничтожение и реконструкция.

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

6 голосов
/ 10 июня 2009

Я бы переместил инициализацию из статического конструктора в метод, который вызывается конструктором. Сделав этот метод внутренним , вы можете затем вызвать этот метод из своих тестов для повторной инициализации класса.

public static class MyClass
{
   public static MyClass()
   {
      initialize();
   }

   internal static void initialize()
   {
      // Do initialization (and cleanup if necessary)
   }

   public static void Method1() {}
   public static void Method2() {}
}

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

Вы также можете сделать его приватным, но тогда вам нужно использовать рефлексию для его вызова.

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

1 голос
/ 10 июня 2009

Не зная, что использование класса комментирует только его использование, это немного сложно, но в любом случае, я не справлюсь. Для меня вышеупомянутое звучит как запах больше, чем проблема тестирования.

Статический класс (так же, как синглтоны) - это набор глобальных функций / переменных, что, как правило, плохо в oop. Я бы сказал, что попытка проверить проблему с тестом (хотя, возможно, самая простая на данный момент) устраняет только симптом, но не проблему.

Я бы посоветовал взглянуть на дизайн Конседера, если вам действительно нужен статический класс или если это просто самый простой способ решить проблему в данный момент

0 голосов
/ 23 декабря 2017

Для полноты картины, если вам нужно сбросить закрытое поле / переменную статического класса, это также можно сделать с помощью отражения.

using System.Reflection; // or Mono.Reflection

public static class MyClass{
    private static string myString;
}

var newValue = "Potatoes";            
var field = typeof(MyClass).GetField("myString", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, newValue); // the first null is because the class is static, the second is the new value
0 голосов
/ 10 июня 2009

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

Попробуйте вместо этого извлечь логику инициализации в отдельный (нестатический) класс.

Ради обсуждения, скажем, ваш статический класс называется MySingleton, и давайте создадим новый класс MyInitializer с методом Execute. Статический конструктор MySingleton может создавать экземпляр MyInitializer и вызывать Execute, который выполняет всю инициализацию.

Тогда ваш производственный код может использовать MySingleton и игнорировать MyInitializer. С другой стороны, ваши тесты могут игнорировать MySingleton и весело создавать новый экземпляр MyInitializer для каждого теста, каждый раз получая новый старт.

0 голосов
/ 10 июня 2009

Вы могли бы использовать Изолятор Typemock , который способен высмеивать статические классы, поэтому в каждом тесте вы можете «определить», как будет работать статический.

Это не бесплатный продукт.

0 голосов
/ 10 июня 2009

Ну, вы не указали, какой язык вы используете, но если есть способ открыть ваш статический класс из тестового файла, то я бы добавил к нему поддельный деструктор, который вы можете вызывать после каждого тестовое задание. Таким образом, «деструктор» остается в тестовом классе и за пределами вашего производственного кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...