Ответ 1
Отличная статья об этом Синглтоны - это патологические лжецы. Это описывает, используя простой пример, почему тестирование с использованием синглтонов неожиданно затруднено.
Я читал случаи за и против использования шаблона singleton. В одном распространенном случае описываются трудности в модульном тестировании с помощью синглтонов, но я неясен, почему это так? Если unit test является частью сборки, вы не могли бы просто ссылаться на синглтон и использовать его, когда это необходимо? (Я думаю с точки зрения java, но я думаю, это не должно иметь значения)
Отличная статья об этом Синглтоны - это патологические лжецы. Это описывает, используя простой пример, почему тестирование с использованием синглтонов неожиданно затруднено.
Если вы ссылаетесь на одноэлементный класс, который существует вне тестируемого класса, то у вас больше нет истинного unit test. Вместо тестирования отдельного модуля - целевого класса - теперь вы тестируете два блока - целевой класс и синглтон.
Существует также тот факт, что одноточечные объекты имеют тенденцию иметь состояние. Чтобы модульные тесты были повторяемыми, эти изменения состояния должны быть отброшены при завершении unit test. Кроме того, вам нужно создать макетную версию синглтона, которая уничтожается после запуска каждого теста. Либо добавляет достаточное количество накладных расходов, как в исходном коде, так и во время работы.
Поскольку singleton является глобальной переменной OOPish. В принципе, все функции, основанные на использовании синглтона (прямо или косвенно), не гарантируются как детерминированные (т.е. Вы не можете ожидать, что функция будет возвращать одни и те же выходы для одних и тех же входов T каждый раз).
TL; DR Тот же объект разделяется между всеми тестами, которые могут стать болью.
Если singleton содержит некоторое состояние, и вы выполняете несколько тестов на нем, тогда заказ тестов может стать проблемой. Представьте себе однострочный "MailStore", в котором содержится список сообщений. Я хочу написать unit test для перечисления писем, а другой для их удаления.
Конечно, если "список" работает до "delete", возможно, это нормально. Если "delete" пробегает перед "списком", то мы боремся, потому что ничего не удалять. (Результаты изменяются в зависимости от порядка выполнения тестов.)
Этот Google Techtalk довольно хорошо описывает проблемы с синглонами и глобальным состоянием, когда дело доходит до модульного тестирования.
Синглтоны являются проблемой по нескольким причинам:
Я не помню, чтобы когда-либо читал это, но я подозреваю, что проблема заключается в том, что вы можете только создать его. В некоторых случаях это может не быть проблемой, просто проверьте его как обычно.
Но что, если вы хотите создать и протестировать другой, возможно, с различными параметрами метода конструктора / factory? Вы перезапускаете JVM? Или создать свой синглтон, чтобы он не был синглом и не мог быть reset? Нехорошо.