Ho letto casi a favore e contro l'utilizzo del modello singleton. Un caso comune contro descrive le difficoltà nei test unitari con i singleton, ma non sono chiaro perché sia così? Se il test unitario fa parte della build non potresti semplicemente fare riferimento al singleton e usarlo quando è necessario? (Sto pensando da una prospettiva java ma immagino che non dovrebbe importare)Perché è difficile testare un sistema che dipende dai singleton?
risposta
Un grande articolo su questo è Singletons are Pathological Liars. Questo descrive, usando un semplice esempio, perché testare usando i singletons è inaspettatamente difficile.
This Google Techtalk fa un buon lavoro di descrizione dei problemi con singoletti e stato globale quando si tratta di test delle unità.
Non ricordo di averlo mai letto, ma sospetto che il problema sia il fatto che è possibile creare solo uno. In alcuni casi, questo potrebbe non essere un problema, basta testarlo normalmente.
Ma cosa succede se si desidera creare e testarne uno diverso, magari con diversi parametri del metodo costruttore/fabbrica? Riavvia la JVM? Oppure crea il tuo singleton in modo che non sia il veramente un singleton e possa essere resettato? Non bene.
Se si fa riferimento a una classe singleton che esiste al di fuori della classe sottoposta a test, non si ha più un vero test di unità. Invece di testare una singola unità - la classe target - ora stai testando due unità: la classe target e il singleton.
C'è anche il fatto che gli oggetti singleton tendono ad avere uno stato. Affinché i test unitari siano ripetibili, è necessario eseguire il rollback di tali cambiamenti di stato al termine del test dell'unità. In alternativa, devi creare una versione fittizia del singleton che viene distrutta dopo l'esecuzione di ogni test. O aggiunge una notevole quantità di overhead, sia nel codice sorgente che nel tempo di esecuzione.
Poiché il singleton è una variabile globale OOPish. Fondamentalmente, tutte le funzioni che si basano sull'uso del singleton (direttamente o indirettamente) non sono garantite per essere deterministiche (cioè non ci si può aspettare che la funzione restituisca le stesse uscite per gli stessi ingressi T ogni esecuzione).
Singletons sono un problema per diversi motivi:
- Si tratta di un caso particolare di un Service Locator, che fornisce un meccanismo per "farmi una di quelle" che non è necessariamente facile da ignorare quando necessario.
- Forniscono un punto di ingresso per leggere o scrivere variabili globali. Il raggruppamento di tali variabili globali in un oggetto con una sola istanza accessibile a livello globale tramite il modello Singleton non comporta magicamente il blocco delle variabili globali.
- Sono problemi anche per la manutenzione. Ad esempio, cosa succede quando smettono di essere un vero Singleton? Forse devi accedere a due database invece che al "database"?
TL; DR Lo stesso oggetto è condiviso tra tutti i test, che può diventare un dolore.
Se il singleton contiene uno stato e vengono eseguiti più test su di esso, l'ordinamento dei test può diventare un problema. Immagina un singleton "MailStore", che contiene un elenco di messaggi. Voglio scrivere un test unitario per elencare i messaggi e un altro per eliminarli.
Ovviamente se la "lista" viene eseguita prima dell'eliminazione, forse è ok. Se "cancella" viene eseguito prima della "lista", allora abbiamo difficoltà perché non c'è nulla da eliminare. (I risultati cambiano a seconda dell'ordine in cui vengono eseguiti i test.)
- 1. Come testare un componente che dipende dai parametri di ActivatedRoute?
- 2. Come testare la logica che dipende dalla data corrente
- 3. Come testare una classe Singleton?
- 4. che deride una classe singleton
- 5. Perché è così difficile fare un ciclo in T-SQL
- 6. In un'architettura distribuita, perché è difficile gestire le versioni?
- 7. C++ 11 Funzione modello che utilizza una funzione std :: che dipende dai parametri del modello
- 8. Come testare la classe Singleton - C++?
- 9. Perché SignalR dipende da jQuery
- 10. Perché determinare se una funzione è puramente difficile?
- 11. Perché è così difficile convertire XML in pdf?
- 12. Perché la profilazione della memoria nel rubino è così difficile?
- 13. Java 7 diamond operator: perché è stato difficile implementarlo?
- 14. Perché è presumibilmente "difficile" distribuire Ruby on Rails alla produzione?
- 15. metafisica CSS: PERCHÉ l'allineamento verticale della pagina è così difficile?
- 16. Qual è l'alternativa a Singleton
- 17. L'implementazione delle librerie C dipende dal sistema operativo?
- 18. Come testare unitamente un'azione del controller MVC che dipende dall'autenticazione in C#?
- 19. Perché utilizzare singleton anziché statico?
- 20. Singleton - Perché usare le classi?
- 21. Non è difficile riconoscere una decrittazione corretta?
- 22. Perché la velocità di questo risolutore SOR dipende dall'input?
- 23. Singleton e unità di test
- 24. JUnit Scheduler che non dipende da Android
- 25. Come schernire i bambini attori per testare un sistema Akka?
- 26. Come testare i buffer overflow su un sistema moderno?
- 27. Creare errori di rete per testare un sistema distribuito
- 28. Un codice Java semplice che funziona bene ma le funzioni in un modo che è un po 'difficile da seguire
- 29. È corretto utilizzare un proxy del servizio Web ASMX singleton?
- 30. Come esprimere che un file di mappa dipende da add_executable?
Il collegamento è interrotto. – Emil
Funziona bene qui. –
Ottimo articolo, +1. L'unica cosa che vorrei che l'articolo cambiasse è l'esempio finale ... per me ha più senso che il metodo charge() sia sul CreditCardProcessor e che abbia preso la carta e l'ammontare come parametri :) – rmeador