top of page

Testen en Domain Driven Design: een krachtige combinatie!


Eerder deze week coachte ik in een DDD-sessie met Tactical DDD als primaire doelstelling. Tactical als in, de focus op Aggregates, Entities, ValueObjects en dergelijke, en de vraag: "Hoe testen we (onze code) bij het uitvoeren van DDD?" kwam naar boven.

Geweldige kans, want code testen, wanneer je DDD doet, is gewoon bevredigend. De eenvoud ervan betekent dat we in principe White Box Unit Testing kunnen doen.

Het is een must om een Onion-architectuur voor het domein te hebben, omdat we ons dan kunnen concentreren op de bedrijfsregels en problemen met de laad- en opslagstatus kunnen negeren.

Ten tweede - gebruik een functionele programmeerstijl, wat betekent dat u altijd "iets" retourneert (vermijd void) en dat "iets" een typefout of gebeurtenis is.



Voorbeeld van magazijn


In een Warehouse kunnen we een Section hebben waar we Goods opslaan. Goods zijn ValueObjects met een aantal fysieke attributen en een Identifier zoals EAN-nummer. Voor de eenvoud zeggen we dat Goods alleen Weight en ID hebben.

Een sectie heeft een maximaal gewicht (regel om te testen), het magazijn staat geen sectieduplicaten toe (regel om te testen).

Sectie is een Entiteit en Warehouse is een Entiteit Aggregate (root). Op de Root Aggregate leggen we bloot:


 

fun addSection( id: SectieID ) : Ofwel

fun addGoodsToSection(id: SectionID, goederen: Goederen) : Beide


Al onze unittests hebben dit eenvoudige patroon (de code is opzettelijk gecomprimeerd om deze kort te houden):

@Test

// Gegeven: Geen secties, het toevoegen van sectie zou "SectionAdded" moeten opleveren

val magazijn = WareHouse()

val sectie = Sectie( SectieID("mySectieID"), maxGewicht = 20)

val expectEvent : Ofwel = Ofwel.right(SectieToegevoegd("mijnSectieID"))

// Wanneer

var actueel : Ofwel = warehouse.addSection(sectie)

// Dan

assert(verwachte gebeurtenis, actueel)


// Gegeven: Het toevoegen van een bestaande sectie zou "Fout" moeten opleveren

val expectError : Beide = Either.left( Error("mySectionID bestaat al"))

// Wanneer

actueel = warehouse.addSection(sectionId)

// Dan

assert(verwachtError, actueel)


@Test

// Gegeven een lege sectie met max. 20, zou het toevoegen van goederen met een gewicht van 30 moeten resulteren in een fout

val magazijn = WareHouse()

val sectie = Sectie( SectieID("aSectieID"), maxGewicht = 20)

magazijn.addSection(sectieId)

waarde goederen = Goederen("#EAN:0123456789", 30 )

val expectError : Beide = Ofwel.Left( Error("MaximumGewichtZouOverschrijden"))

// Wanneer

val actueel = warehouse.addGoodsToSection(sectie.id, goederen)

// Dan

assert(verwachtError, actueel)


 

Eenvoudige test

Omdat we altijd een Response krijgen en we ons niet bezig hoeven te houden met het laden/opslaan van Data, wordt elke test eenvoudig. We kunnen zelfs (misschien niet de beste praktijken) een continue testflow in één keer uitvoeren, zoals getoond in de eerste Test.

Hoe u aggregaten laadt en opslaat (de objectgrafiek met gegevens vult), valt buiten het bestek van dit artikel. Maar zoals altijd geldt: als u vragen hebt of benieuwd bent hoe DDD jou kan helpen, stuur dan gerust een bericht. Ik neem dan contact met je op.

Tags:

0 opmerkingen

Recente blogposts

Alles weergeven

Comments


bottom of page