Почему сложно провести модульное тестирование системы, которая зависит от синглетонов? - PullRequest
24 голосов
/ 07 октября 2010

Я читал случаи за и против использования шаблона синглтона. Один распространенный случай против описывает трудности в модульном тестировании с одиночками, но мне неясно, почему это так? Если модульный тест является частью сборки, не могли бы вы просто сослаться на синглтон и использовать его, когда это необходимо? (Я думаю с точки зрения Java, но я думаю, это не имеет значения)

Ответы [ 7 ]

18 голосов
/ 07 октября 2010

Отличная статья об этом: Синглтоны - это патологические лжецы . На простом примере описывается, почему тестирование с использованием синглетонов неожиданно сложно.

5 голосов
/ 07 октября 2010

Если вы ссылаетесь на одноэлементный класс, который существует за пределами тестируемого класса, то у вас больше не будет истинного модульного теста. Вместо того, чтобы тестировать одну единицу - целевой класс - теперь вы тестируете две единицы - целевой класс и синглтон.

Существует также тот факт, что одиночные объекты имеют тенденцию иметь состояние. Чтобы модульные тесты были повторяемыми, эти изменения состояния необходимо откатить после завершения модульного теста. В качестве альтернативы, вы должны создать фиктивную версию синглтона, которая будет уничтожена после каждого теста. Либо добавляет изрядное количество накладных расходов, как в исходном коде, так и во время выполнения.

4 голосов
/ 26 февраля 2015

TL; DR Один и тот же объект распределяется между всеми тестами, что может стать проблемой.

Если в синглтоне содержится какое-то состояние, и вы запускаете на нем несколько тестов, то порядок тестов может стать проблемой. Представьте себе единый «MailStore», который содержит список сообщений. Я хочу написать модульный тест для перечисления писем, а другой - для их удаления.

Конечно, если «список» запускается до «удаления», возможно, это нормально. Если «delete» выполняется перед «list», то мы боремся, потому что нечего удалять. (Результаты меняются в зависимости от порядка выполнения тестов.)

4 голосов
/ 07 октября 2010

Поскольку синглтон является глобальной переменной OOPish.В принципе, все функции, основанные на использовании синглтона (прямо или косвенно), не гарантированно будут детерминированными (т. Е. Нельзя ожидать, что функция будет возвращать одинаковые выходы для одинаковых входов T каждый и каждый запуск).

3 голосов
/ 07 октября 2010

Синглтоны - это проблема по нескольким причинам:

  • Это особый случай сервисного локатора, который предоставляет механизм для "получения одного из них", который не всегда легко переопределить при необходимости.
  • Они обеспечивают точку входа для чтения или записи глобальных переменных. Заключение этих глобальных переменных в объект только с одним экземпляром, глобально доступным через шаблон Singleton, волшебным образом не перестает быть глобальными переменными.
  • Они тоже проблемы с обслуживанием. Например, что происходит, когда они перестают быть настоящими синглтонами - может быть, вам нужно получить доступ к двум базам данных вместо «базы данных»?
2 голосов
/ 07 октября 2010

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

0 голосов
/ 07 октября 2010

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

Но что, если вы хотите создать и протестировать другой, возможно, с другими параметрами метода конструктора / фабрики? Вы перезапускаете JVM? Или создать свой синглтон, чтобы он не был действительно синглтоном и мог быть сброшен? Не хорошо.

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