Статический класс/метод/свойство в 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 и использоваться только внутри классов, для которых они определены, для внутренних целей. Я рассматриваю публично выставленный статический метод как запах кода.