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

Различные экземпляры Singleton с проверками JUnit

У меня есть автономный синглтон, который успешно проходит тест. Но с группой тестов это терпит неудачу, поскольку, как только один сингл определен, он не позволяет экземпляру reset.

Любые идеи о том, как это сделать?

4b9b3361

Ответ 1

Не используйте синглтон.

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

Вместо этого сделайте конструктор открытым и напишите тесты, используя новые экземпляры. В своей реальной программе используйте getInstance(), чтобы получить канонический глобальный экземпляр (или использовать контейнер IOC).

И помните, что синглтоны являются патологическими лжецами.

Если вы все еще слишком довольны идеей Singleton, вместо того, чтобы публиковать конструктор, вы можете добавить общедоступный (и статический) метод factory для создания экземпляров таким образом, который не может быть использован случайно, например:

public static MyClass TEST_CreateInstance() {
  return new MyClass();
}

Ответ 2

Я предполагаю, что у вас есть приватное статическое поле в вашем одиночном классе для хранения инициализированного экземпляра.

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

Ответ 3

Вы можете добавить метод для уничтожения синглтона, например destroyMe(); где вы деинициализируете все и установите для экземпляра singleton значение null.

  public void destroyMe(){
   this.instance = null;
   //-- other stuff to turn it off.
}

Я оставлю проблемы синхронизации, хотя;)

Но зачем вам повторно инициализировать ваш синглтон для каждого теста? Он не должен отличаться в зависимости от концепции синглтона.

Ответ 4

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

по-прежнему нужно сначала выполнить тесты:


static setInstance(...){ //package visibility or in difficult cases you have to use public
  instance = ...;
}

поскольку это более обходное решение. поэтому сначала загрузите тестовые объекты, а затем переконфигурируйте их из одноэлементного шаблона.

Ответ 5

Я настоятельно рекомендую отойти от Singletons в качестве шаблона проектирования и использовать Singleton в качестве области действия (Injection Dependency). Это просто заставило бы вашу проблему уйти.

Но если вы застряли в мире Singletons, у вас есть несколько вариантов в зависимости от того, тестируете ли вы Singleton или зависимость.

Если вы тестируете зависимый элемент, вы можете высмеять Singleton, используя PowerMock и JMockIt. См. Мой предыдущий пост о насмешливости Runtime.getRuntime для получения инструкций о том, как это сделать.

Если вы тестируете Singleton, вам нужно отменить правила построения или дать Singleton метод "Reset".

Ответ 6

Spring предоставляет аннотацию DirtiesContext для этого конкретного случая использования, где вам нужны новые экземпляры singleton beans для каждого тестового теста, Он в основном создает новый контекст приложения для каждого тестового/тестового класса, который применяет эту аннотацию.

Ответ 7

Экземпляр Singleton должен быть передан SUT самим испытанием - таким образом вы создаете singleton (и уничтожаете) для каждого теста. Принятие IoC и насмешливой структуры, например, Mockito, сделало бы этот подход почти тривиальным.