How can I test the Account class, or event the Money class?
Questa domanda ha un paio di diversi tipi di risposta.
La risposta più semplice è che stiamo usando il modello di dominio per gestire la modifica in un modello di dati . Quella Money.value
proviene da qualche parte, e la motivazione per invocare Account.withdraw
è di cambiare quel valore specifico alla sua origine .
Given: an initial state for the source
When: the domain model is directed to perform a behavior
Then: the change to the source satisfies the specification
Per lo stato della risorsa, pensa DTO; una rappresentazione di quello stato progettato per superare i confini del processo.
La stessa idea è stata espressa in un altro modo: deve esserci un modo per iniettare i dati nella posta del dominio ed estrarla di nuovo. C'è qualcosa che capisce come prendere input primitivi e trasformarli in oggetti valore; e come saggio ci deve essere qualcosa che comprenda come prendere oggetti di valore e convertirli in output primitivi.
Se hai familiarità con TDD, vedi questo approccio adottato durante la progettazione di una nuova classe - considera gioco di bowling kata . I modelli di test rotolano come input int e modellano il punteggio come output int. Quando iniziamo a rendere espliciti questi concetti nel modello, scriviamo il codice per trasformare i primitivi nel concetto esplicito e viceversa.
Una variazione leggermente diversa; quello che stiamo facendo di solito con un modello di dominio è garantire che le modifiche a un libro di record soddisfino alcune invarianze di business. Quindi pensiamo in termini di passare il "book of record" al modello, lasciare che il modello apporti le modifiche e quindi ispezionare il libro del record per verificare le modifiche.
// Given
Model m = Model.from(bookOfRecord);
Command c = Command.from(message);
// When
{
m.runCommand(c);
}
// Then
assert specification.isSatisfiedBy(bookOfRecord);
Una risposta diversa è venuta da Greg Young, quando ha introdotto il kata di probabilità "testare il modello nel calcolo di se stesso ".
Ad esempio, il fatto che, nel tuo esempio, il modello di dominio utilizza un valore in virgola mobile per tracciare lo stato corrente di Money è un dettaglio di implementazione. È uno che probabilmente cambierà mentre il tuo modello diventa più sofisticato sulle regole di arrotondamento.
Questo tipo di modifica non dovrebbe interrompere tutti i test.
Lo "stato" del modello dovrebbe essere una scatola nera; ciò su cui i test dovrebbero essere focalizzati non è che il modello finisca nello "stato" atteso, ma invece che il modello produca le giuste risposte a query .
Alcune di queste query potrebbero essere semplici come "il modello è internamente coerente?"