Skip to content
This repository has been archived by the owner on May 27, 2020. It is now read-only.

DSL for testing aggregates and events using domain language

Notifications You must be signed in to change notification settings

CJSCommonPlatform/domain-test-dsl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Domain Test DSL

Deprecated

This project has moved to be a sub-project of Framework Libraries and is located here

Pull requests against this project have been disabled. Please contact one of the project owners for emergency bug fixes on this version

A domain-specific language (DSL) for testing aggregate roots and events using domain language:

  • Given/When/Then based
  • Feature files contain scenarios in plain language that business people can understand
  • The Domain Test DSL library automatically tests the Java code implementing aggregate roots according to the behaviour described in the feature files

Example

The implementation of our business domain is event sourced, so we can describe the current state (the Given clause) as a list of events that have already happened. When we perform an action on our domain model (the When clause), the result (the Then clause) will always be a list of events that have now occurred as a consequence:

Scenario: Add ingredients to a recipe

Given recipe added

When you addIngredients to a Recipe from an ingredients list

Then ingredients added

How it works

The language heavily relies on the simple pattern implemented by the Aggregate interface in framework. Every interaction with an aggregate root follows the same pattern:

  1. Events that have occurred previously are applied to the aggregate root
  2. An action is performed on the aggregate root by calling one of its methods with some arguments
  3. Zero or more events are consequently emitted by the aggregate root

Since the Given and Then clauses are simply lists of event descriptions, the only complex part of this is the When clause. In order to interpret this, we need it to follow a fixed grammatical structure:

When you <do something> to an <aggregate root> using <some new information>

  • <do something> is the action being performed, and has to be the method being called on the aggregate root
  • <aggregate root> is the name of the Java class implementing the aggregate root
  • <some new information> is optional, but if present is the data used to perform the action; the arguments passed to the method being called
  • The joining words that can be used are specified by the Domain Test DSL library, but offer a flexible set of choices designed to allow phrases to read as close to well-written English as possible

In terms of the code implementation, events and input data are provided as JSON files. The example scenario above translates to the following steps when running the test:

  1. Create a new instance of the aggregate root class Recipe.
  2. Load some data for a RecipeAdded event from a JSON file called recipe-added.json
  3. Apply the RecipeAdded event to the Recipe aggregate root
  4. Load some data for the action from a JSON file called ingredients-list.json
  5. Call the addIngredients method on the Recipe using the action data
  6. Collect the events emitted from the action method
  7. Assert that the collected events match the event data in a file called ingredients-added.json

recipe-added.json

{
  "_metadata": {
    "name": "recipe-added"
  },
  "recipeId": "5c5a1d30-0414-11e7-93ae-92361f002671",
  "name": "Cheese Cake",
  "glutenFree": true
}

ingredients-list.json

{
  "ingredients": [{
      "name": "sugar",
     "quantity": 500
    }, {
      "name": "custard",
      "quantity": 2
    }
  ]
}

ingredients-added.json

{
  "_metadata": {
    "name": "ingredients-added"
  },
  "recipeId": "5c5a1d30-0414-11e7-93ae-92361f002671",
  "ingredients": [{
      "name": "sugar",
     "quantity": 500
    }, {
      "name": "custard",
      "quantity": 2
    }
  ]
}