Różne instancje Singletona z testami JUnit
Mam samodzielny singleton, który pomyślnie przechodzi test. Ale w przypadku grupy testów to się nie powiedzie, ponieważ po zdefiniowaniu Singletona nie pozwala na resetowanie instancji.
Jakieś pomysły jak to zrobić?
7 answers
Nie używaj Singletona.
W szczególności, jedyną różnicą między zmienną singleton a zmienną globalną jest to, że singleton próbuje wymusić pojedynczą instancję (na przykład przez uczynienie konstruktora prywatnym).
Zamiast tego upublicznij konstruktor i napisz testy używając nowych instancji. W twoim programie użyj getInstance()
, Aby uzyskać globalną instancję canonical (lub użyj kontenera IOC).
I pamiętaj, że singletony są patologicznymi kłamcami.
Jeśli zamiast publikować konstruktor, możesz dodać publiczną (i statyczną) metodę fabryczną, aby tworzyć instancje w sposób, który nie może być użyty przez przypadek, np.:
public static MyClass TEST_CreateInstance() {
return new MyClass();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-01 21:09:25
Zakładam, że masz prywatne statyczne pole w klasie singleton do przechowywania zainicjowanej instancji.
Jeśli nie chcesz modyfikować kodu, możesz zdefiniować metodę teardown, która będzie uruchamiana po każdym teście i w tej metodzie ustawisz to statyczne pole NA null poprzez odbicie, jak pokazano tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:29
Możesz dodać metodę zniszczenia Singletona, na przykład destroyMe (); gdzie wszystko deinicjalizujesz i ustawiasz instancję Singletona NA null.
public void destroyMe(){
this.instance = null;
//-- other stuff to turn it off.
}
Zostawię jednak problemy z synchronizacją;)
Ale dlaczego musisz ponownie inicjować swój singleton dla każdego testu? Nie powinno się różnić w oparciu o koncepcję Singletona.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-15 17:49:17
I gorąco zalecam odejście od singletonów jako wzorca projektowego i użycie Singletona jako zakresu (iniekcji zależności). To po prostu sprawi, że twój problem zniknie.
Ale zakładając, że utknąłeś w świecie singletonów, masz kilka opcji w zależności od tego, Czy testujesz Singleton, czy zależność.
Jeśli testujesz element zależny, możesz wyśmiewać Singleton używając PowerMocki JMockIt. Zobacz mój poprzedni post o wyśmiewaniu Runtime.getRuntime dla instrukcji, Jak to zrobić.
Jeśli testujesz Singleton, musisz rozluźnić zasady budowy lub dać Singletonowi metodę "Reset".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:29:41
Generalnie uważaj na singletony, najczęściej są one złe, złe i mają tendencję do reprezentowania dużych zmiennych globalnych (co jest złe dla utrzymania).
Jeszcze żeby najpierw zrobić testy możesz zrobić:
static setInstance(...){ //package visibility or in difficult cases you have to use public
instance = ...;
}
Jak powiedział, Jest to bardziej obejście. więc zdobądź pierwsze miejsce testów, ale potem refaktor z dala od wzoru Singletona.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-30 07:55:27
Spring zapewnia adnotację DirtiesContext dla tego konkretnego przypadku użycia, w którym potrzebujesz nowych wystąpień ziaren Singletona dla każdej skrzynki testowej. Zasadniczo tworzy nowy kontekst aplikacji dla każdej skrzynki testowej / klasy testowej, w której zastosowano tę adnotację.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-18 08:25:17
Instancja Singletona musi zostać przekazana do SUT przez sam test - w ten sposób tworzysz singleton (i niszczysz) dla każdego testu. Przyjęcie IoC I wyśmiewanie RAM, jak Mockito, uczyniłoby to podejście niemal banalnym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-01 20:58:47