Мне нужен одиночный элемент в моем коде. Я реализовал его в Java, и это работает хорошо. Причина я сделал это, должен гарантировать, что в mulitple среде, существует только один экземпляр этого класса.
Но теперь я хочу протестировать свой объект Singleton локально с Модульным тестом. Поэтому я должен моделировать другой экземпляр этой Singleton (объект, который был бы от другого устройства). Так есть ли возможность инстанцировать Singleton во второй раз для тестирования цели, или я должен дразнить его?
Я не уверен, но я думаю, что это могло быть возможно при помощи другого загрузчика класса?
Вы можете вызвать частный конструктор вашего класса singleton, используя отражение, чтобы создать новый экземпляр класса.
class MySingleton {
private MySingleton() {
}
}
class Test {
public void test() throws Exception {
Constructor<MySingleton> constructor = MySingleton.class.getConstructor();
constructor.setAccessible(true);
MySingleton otherSingleton = constructor.newInstance();
}
}
Я чувствую себя обязанным опубликовать эту серию статей о том, как синглтоны разрушают тестируемость и являются плохим выбором дизайна:
Краткое резюме: сочетание логики того, что делает класс, с тем, как он создается, делает код некрасивым для тестирования, и его следует избегать.
Суть синглтона в том, что его можно создать только один раз.
Во-первых, почему вам нужно создавать новый синглтон для запуска модульного теста? Юнит-тест не должен выполняться одновременно с обычным приложением, поэтому вы должны иметь доступ к исходному синглтону, не опасаясь его модификации...
Есть ли конкретная причина, по которой вам нужен явный второй синглтон?
вы можете просто создать другой статический метод getInstance2
, который выглядит так:
class MySingleton
{
private MySingleton(){}
private static MySingleton instance1 = new MySingleton();
private static MySingleton instance2 = new MySingleton();
public static MySingleton getInstance(){ return instance1; }
public static MySingleton getInstance2(){ return instance2; }
}
Одноэлементный объект по определению может быть создан только один раз. Однако тот факт, что вашему модульному тесту требуется два синглтона, убедительно свидетельствует о том, что ваш объект не должен быть синглтоном , и что вам следует переосмыслить дизайн синглтона.
Традиционно синглтон создает свой собственный экземпляр, причем только один раз. В этом случае создать второй экземпляр невозможно.
Если вы используете внедрение зависимостей, вы можете позволить фреймворку создать за вас синглтон. Синглтон не защищает от других экземпляров (т. Е. Имеет общедоступный конструктор), но структура внедрения зависимостей создает только один экземпляр. В этом случае вы можете создать больше экземпляров для тестирования, и ваш объект не будет загроможден одноэлементным кодом.