Статический класс/метод/свойство в unit test, остановить или нет

Обновление

должен ли использоваться статический класс/метод/свойство в среде разработки unit test, учитывая, что он не может протестировать его без введения обертки, которая снова не тестируется?

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

Ответы

Ответ 1

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

В целом, нет ничего плохого (например, он не прерывает модульное тестирование /TDD ) со статическими методами, когда:

  • это просто, метод ввода-вывода (все виды "вычисляют это с учетом этого" )
  • он надежный, под которым мы подразумеваем либо тестируемую вами единицу, либо исходит от стороннего источника, который вы считаете надежным (например, Math.Floor можно считать надежным - использование его не должно повышаться "Осторожно, оно статично!" предупреждение, можно предположить, что Microsoft выполняет свою работу)

Когда статические методы вызовут проблемы и их следует избегать? В основном, только когда они взаимодействуют с / делают что-то, что вы не можете контролировать (или mock):

  • все виды файловой системы, базы данных, сетевых зависимостей
  • другие (возможно, более сложные) статические методы, вызываемые изнутри
  • в значительной степени все, с чем ваша смешная структура не может справиться на регулярных условиях.

Изменить: два примера, когда статический метод будет жестко тестировать устройство

1

public int ExtractSumFromReport(string reportPath)
{
     var reportFile = File.ReadAllText(reportPath);
     // ...
}

Как вы относитесь к File.ReadAllText? Это, очевидно, перейдет в файловую систему для извлечения содержимого файла, что является серьезным нет-нет при модульном тестировании. Это пример статического метода с внешней зависимостью. Чтобы этого избежать, вы обычно создаете оболочку вокруг файловой системы api или просто вводите ее как зависимость/делегат.

2

public void SaveUser(User user)
{
    var session = SessionFactory.CreateSession();
    // ...
}

Как насчет этого? Сессия - нетривиальная зависимость. Конечно, это может быть как ISession, но как заставить SessionFactory вернуть mock? Мы не можем. И мы также не можем создавать легкоотдаваемые объекты сеанса.

В таких случаях, как указано выше, лучше всего избегать статических методов.

Ответ 2

Статические методы CAN будут протестированы. Их не могут насмехаться (в общем, есть некоторые рамки для этого, например Moles.

Ответ 3

Вы не можете издеваться над статическими методами/свойствами. Итак, когда ваш classA использует какой-то статический член classB, вы не можете изолировать classA.

UPDATE: я не вижу проблемы с переносом некоторого статического класса в объект. Это не занимает много времени, но это позволяет уменьшить сцепление в вашей системе.

Ответ 4

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