Examples that test the model
A scenario is one example of one rule. It shows how a slice behaves.
After this page, you can:
- write a Given, When, Then example for a Command and for a Read Model
- name the seven kinds of example that every Command needs
- show a refused Command and an empty list in a way that a reader can check
One rule, one example
A scenario is an example of one business rule. It has three parts. Given says what already happened. When names the action. Then states the result. Use business words and concrete values.
| Kind | Given | When | Then |
|---|---|---|---|
| State Change | Earlier Events. An empty list means no history. | At most one Command. | The new Events, or an expected refusal. |
| State View | The source Events. | Nothing. | One Read Model, with its content. |
| Automation | Setup Events first, and the trigger Event last. | Nothing. | The Command that the Automation sends, or nothing. |
| Refusal | Events that make the state invalid. No Events for a plain input check. | The Command. | No Event, and a short reason for the refusal. |
Do not mix Events and a Read Model in one Then. All parts of one scenario come from the same chapter.
Write a good example
Three checks make an example useful:
- The givens are explicit. Write "Order Created exists and Order Confirmed does not", not "an order".
- The action is clear. Write "the customer confirms the order", not "something happens".
- The result can be checked. Write the Event with its values, or the refusal with its reason. "It works" is not a result.
Test a limit on both sides. If a rule allows a loan up to 2 million euros, write one example just below the limit and one just above.
The table shows examples for the clinic. The rules are examples only.
| Title | Given | When | Then |
|---|---|---|---|
| Appointment is added | Pet Added (pet 5) | Add Appointment (pet 5, 10:00) | Appointment Added (pet 5, 10:00) |
| Unknown pet | Nothing | Add Appointment (pet 9, 10:00) | Refused: Pet not found |
| Missing time | Pet Added (pet 5) | Add Appointment (pet 5, no time) | Refused: Time is required |
| Calendar shows it | Appointment Added (pet 5, 10:00) | Nothing | Calendar: one row, pet 5 at 10:00 |
Seven questions for every Command
Do not stop at one good case and one bad case. Ask all seven questions for every Command. Write an example for each answer that applies. If a case cannot happen, write down why.
| # | Kind | The question |
|---|---|---|
| 1 | Happy path | What is the normal success case? |
| 2 | Validation failure | Which invalid or missing inputs does the system refuse? |
| 3 | State violation | In which state is this Command not allowed? |
| 4 | Duplicate action | What happens if someone sends it again after it worked? |
| 5 | Alternative path | Which other valid outcomes depend on the context? |
| 6 | External failure | What happens if an outside system or a timer fails? |
| 7 | Compensation | Can someone undo it? What starts the cleanup? |
Try first: the Command is Confirm Order. Name three examples beyond the happy path.
Show the answer
Three examples: a missing card (validation failure), an order that was canceled (state violation), and a second confirmation of the same order (duplicate action).
Refused or recorded?
Two kinds of failure look alike. Keep them apart.
- A refused Command records no Event. Nothing happened. You write it as an example with a reason.
- A failure that the business tracks is a fact. The payment gateway declines a card, so the system records Payment Failed with the order, the reason, and the time.
Examples for Read Models
Every Read Model needs at least one view example. This includes each todo list. Many Command examples with no view example make an incomplete model.
- Show how the Read Model fills when Events arrive.
- Show how it changes or empties, for example when an item expires or a customer returns an item.
- For a list, give one concrete row for each expected row.
- If the list is empty, write that it is empty on purpose. A missing example can mean that nobody wrote it yet.
- A refusal is not an empty list. Use a refusal only for Commands.
Some Read Models build up over many Events. A balance goes from 40 to 110 after two deposits. For these, write a storyline. A storyline tells one use case as a series of beats. A todo list is a good candidate: it starts empty, gets one row, and is empty again after the work is done.
Check yourself
Make this result checkable: Then, it works.
Answer
Name the Event and its values. For example: Appointment Added with pet 5 and time 10:00.
What is the Given for the example Confirm twice?
Answer
Order Created and Order Confirmed. The second confirmation then refuses with a reason such as "Order already confirmed".
The last appointment is canceled. What does the Calendar example say?
Answer
The Calendar is an empty list. Write that it is empty on purpose.
A payment provider declines a card. Is this a refusal or a recorded fact?
Answer
It is a recorded fact. The business tracks it, so the system records Payment Failed.
Remember:
- A scenario is one example of one rule: Given, When, Then.
- Ask the seven questions for every Command.
- Every Read Model, including each todo list, needs a view example.
- Write an empty list on purpose. Keep refusals for Commands.