Подтвердить что ты не робот

Почему трудно unit test система, которая зависит от одиночных чисел?

Я читал случаи за и против использования шаблона singleton. В одном распространенном случае описываются трудности в модульном тестировании с помощью синглтонов, но я неясен, почему это так? Если unit test является частью сборки, вы не могли бы просто ссылаться на синглтон и использовать его, когда это необходимо? (Я думаю с точки зрения java, но я думаю, это не должно иметь значения)

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

TL; DR Тот же объект разделяется между всеми тестами, которые могут стать болью.

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

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

Ответ 5

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

Ответ 6

Синглтоны являются проблемой по нескольким причинам:

  • Они являются особым случаем локатора сервисов, который предоставляет механизм, чтобы "получить меня один из тех", который не всегда легко переопределить, когда это необходимо.
  • Они предоставляют точку входа для чтения или записи глобальных переменных. Обтекание этих глобальных переменных в объекте только одним экземпляром, доступным по всему миру через шаблон Singleton, не волшебным образом заставляет их перестать быть глобальными переменными.
  • Они тоже заботятся об обслуживании. Например, что происходит, когда они перестают быть истинным Синглтоном - возможно, вам нужно получить доступ к двум базам данных вместо "базы данных"?

Ответ 7

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

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