Проблема не в тестировании самих синглетонов; В книге говорится, что если класс, который вы пытаетесь протестировать , зависит от синглтона, то у вас, вероятно, будут проблемы.
Если только вы (1) не сделаете так, чтобы синглтон реализовывал интерфейс, и (2) внедрили синглтон в ваш класс, используя этот интерфейс.
Например, синглтоны обычно создаются непосредственно так:
public class MyClass
{
private MySingleton __s = MySingleton.getInstance() ;
...
}
MyClass
теперь может быть очень трудно автоматизировать тестирование. Например, как @Boris Pavlović отмечает в своем ответе, если поведение синглтона основано на системном времени, ваши тесты теперь также зависят от системного времени, и вы не сможете тестировать случаи, которые, скажем, зависят от день недели.
Однако, если ваш синглтон «реализует интерфейс, который служит его типом», вы все равно можете использовать реализацию синглтона этого интерфейса, если вы передаете его в:
public class SomeSingleton
implements SomeInterface
{
...
}
public class MyClass
{
private SomeInterface __s ;
public MyClass( SomeInterface s )
{
__s = s ;
}
...
}
...
MyClass m = new MyClass( SomeSingleton.getInstance() ) ;
С точки зрения тестирования MyClass
вам теперь все равно, является ли SomeSingleton
одноэлементным или нет: вы также можете передать любую другую реализацию, какую захотите, включая реализацию синглтона, но, скорее всего, вы будете использовать какой-то макет, который вы контролируете своими тестами.
Кстати, это НЕ способ сделать это:
public class MyClass
{
private SomeInterface __s = SomeSingleton.getInstance() ;
public MyClass()
{
}
...
}
Это все равно работает во время выполнения, но для тестирования вы снова зависите от SomeSingleton
.