Sto provando a testare (o almeno scrivere test di unità) sulle mie classi Model ma ho notato che le mie classi finiscono per essere troppo accoppiate. Poiché non riesco a rompere questo accoppiamento, scrivere test di unità sta diventando sempre più difficile.
Per essere più specifici:
Classi di modelli: sono le classi che contengono i dati nella mia applicazione. Assomigliano più o meno al POJO (semplici vecchi oggetti Java), ma hanno anche alcuni metodi. L'applicazione non è troppo grande quindi ho circa 15 classi di modelli.
Accoppiamento : solo per fare un esempio, pensa a un semplice caso di Order Header - > Ordine Articolo. L'intestazione conosce l'elemento e l'elemento conosce l'intestazione (richiede alcune informazioni dall'intestazione per l'esecuzione di determinate operazioni). Quindi, diciamo che esiste la relazione tra l'articolo dell'ordine - > Rapporto sull'articolo Il report dell'articolo ha bisogno anche dell'oggetto. A questo punto, immagina di scrivere test per il report degli articoli; è necessario avere un'intestazione dell'ordine per eseguire i test. Questo è un caso semplice con 3 classi; le cose si complicano con più classi.
Posso creare classi disaccoppiate quando disegno algoritmi, livelli di persistenza, interazioni utente, ecc ... ma con le classi modello, non riesco a pensare a un modo per separarli. Attualmente siedono come una grande fetta di classi che dipendono l'una dall'altra.
Ecco alcuni accorgimenti che posso pensare:
- Generatori di dati : ho un pacchetto che genera dati di esempio per le mie classi di modelli. Ad esempio, la classe OrderHeaderGenerator crea OrderHeaders con alcuni dati di base. Uso OrderHeaderGenerator dai miei unit-test ItemReport in modo da ottenere un'istanza sulla classe OrderHeader. Il problema è che questi generatori si complicano molto velocemente e quindi ho bisogno di testare questi generatori; sconfiggere un po 'lo scopo.
- Interfacce anziché dipendenze : posso creare interfacce per sbarazzarsi delle durissime dipendenze. Ad esempio, la classe OrderItem dipende dall'interfaccia IOrderHeader. Quindi, nei miei test unitari, posso facilmente prendere in giro il comportamento di un OrderHeader con una classe FakeOrderHeader che implementa l'interfaccia IOrderHeader. Il problema con questo approccio è la complessità che le classi del modello finirebbero per avere.
Avresti altre idee su come rompere questo accoppiamento nelle classi modello? Oppure, come rendere più semplice il test unitario delle classi del modello?
Aggiornamento dopo aver esaminato le risposte:
- Ho riflettuto un po 'su questo problema e ho notato che alcune di queste dipendenze non erano realmente necessarie (come sottolineato dalla maggior parte delle risposte). Il motivo per cui esistevano è perché il mio livello di interfaccia utente ne aveva bisogno. Fondamentalmente, ho inserito queste dipendenze in modo che il livello dell'interfaccia utente possa facilmente navigare da bambino all'intestazione e visualizzare alcuni campi di intestazione nelle viste a livello figlio. Guardandolo ora, sembra così semplice; tuttavia mi ci è voluto del tempo per capire perché queste dipendenze esistevano in primo luogo. Ora, l'interfaccia utente manterrà fondamentalmente l'intestazione nel suo contesto durante la navigazione verso le visualizzazioni a livello figlio.
- D'altra parte, ho rimosso alcune delle dipendenze tramite interfacce. Queste dipendenze erano principalmente one-to-one; per esempio tra Header e HeaderReport. In precedenza, HeaderReport dipendeva dall'intestazione per il recupero delle informazioni (elementi, data, ecc.) E ciò rendeva molto difficile testare HeaderReport. Ora, HeaderReport dipende dall'interfaccia HeaderDataProvider e sono in grado di ottenere l'isolamento completo. HeaderReport è molto facile da testare con le classi stub per l'interfaccia HeaderDataProvider.
- Sembra facile creare queste astrazioni (UI Layer - Model Layer - Backend Layer), tuttavia in realtà ci vuole molta pratica!