As I am not really experienced in unit testing, I am trying to gather some rules that I will learn first.
Stai attento a imparare "regole" per problemi che non hai mai incontrato. Se ti imbatti in "regole" o "best practice", ti suggerirei di trovare un semplice esempio di giocattolo in cui questa regola è "supposta" da usare e di cercare di risolvere quel problema te stesso , ignorando cosa dice la "regola".
In questo caso, potresti provare a creare 2 o 3 classi semplici e alcuni comportamenti da implementare. Implementare le classi in qualsiasi modo si senta naturale e scrivere un test unitario per ogni comportamento. Fai una lista di tutti i problemi che hai riscontrato, ad es. se avevi iniziato a lavorare in un modo, allora dovevi tornare indietro e cambiarlo più tardi; se sei confuso su come le cose dovrebbero combaciare; se ti dava fastidio scrivere a boilerplate; ecc.
Quindi prova a risolvere lo stesso problema seguendo la "regola". Di nuovo, fai una lista dei problemi che hai incontrato. Confronta le liste e pensa a quali situazioni potrebbero essere migliori quando si segue la regola, e quali no.
Per quanto riguarda la tua domanda, tendo a favorire un approccio per porte e adattatori , dove facciamo una distinzione tra "core logic" e "services" (questo è simile alla distinzione tra pure funzioni e procedure efficaci).
La logica di base si basa sul calcolo delle cose "all'interno" dell'applicazione, in base al dominio del problema. Potrebbe contenere classi come User
, Document
, Order
, Invoice
, ecc. Va bene che le classi di core chiamino new
per altre classi core, dal momento che sono dettagli di implementazione "interni". Ad esempio, la creazione di un Order
potrebbe anche creare un Invoice
e un Document
che dettagliano ciò che è stato ordinato. Non c'è bisogno di prendere in giro questi durante i test, perché queste sono le cose reali che vogliamo testare!
Le porte e gli adattatori sono il modo in cui la logica principale interagisce con il mondo esterno. Qui è dove cose come Database
, ConfigFile
, EmailSender
, ecc. Dal vivo. Queste sono le cose che rendono difficile il testing, quindi è consigliabile creare queste all'esterno della logica di base e passarle in base alle necessità (con l'iniezione della dipendenza, o come argomenti del metodo, ecc.).
In questo modo, la logica di base (che è la parte specifica dell'applicazione, in cui vive la logica aziendale importante ed è soggetta al maggior numero di churn) può essere testata da sola, senza doversi preoccupare di database, file, e-mail , ecc. Possiamo solo passare alcuni valori di esempio e controllare che otteniamo i giusti valori di output.
Le porte e gli adattatori possono essere testati separatamente, usando i mock per il database, il filesystem, ecc. senza doversi preoccupare della logica di business. Possiamo semplicemente passare alcuni valori di esempio e accertarci che vengano memorizzati / letti / inviati / ecc. opportunamente.