Learn ยท 04 of 5

Scenarios: make the slice testable

A scenario lives beside its workflow and describes one business rule using typed steps.

WorkflowGivenWhenThenCardinality
State ChangeEventCommandEvent or Errorzero or more given, one when, one or more then
State ViewEventnoneRead Model or Errorone or more given, zero when, one or more then
Automation / TranslationEvent or Read ModelProcessor or CommandEvent or Errorone when, one or more then

Each step has one typed target. An error target contains a literal string.

State Change scenario

Given Event(s) When Command Then Event or Error bounded_context "owner_management" { event "owner_registered" { } } bounded_context "pet_management" { event "pet_added" { } } state_change "add_pet" { command "add_pet_command" { to = [event.pet_management.pet_added] } scenario "add_pet_success" { given { event = event.owner_management.owner_registered } when { command = command.add_pet_command } then { event = event.pet_management.pet_added } } }

An error path uses a different then target. An optional comment records the business rule:

bounded_context "pet_management" { event "pet_added" { } } state_change "add_pet" { command "add_pet_command" { to = [event.pet_management.pet_added] } scenario "add_pet_validation_error" { when { command = command.add_pet_command } then { error = "Pet name is required" } comment { description = "A pet must have a name before it can be registered." } } }

State View scenario

Given Event(s) Then Read Model or Error

For example: given Student Registered, then Students to Welcome.

bounded_context "students" { event "student_registered" { } } state_view "welcome_students" { readmodel "students_to_welcome" { question = "Which registered students still need a welcome?" from = [event.students.student_registered] } scenario "registered_student_needs_welcome" { given { event = event.students.student_registered } then { readmodel = readmodel.students_to_welcome } } }

State View: one or more Event given steps, no when, and one or more Read Model or Error then steps.

Working from an older draft? See the migration guide for the removed Query form.

Automation / Translation scenarios

given targets an Event or Read Model, when targets a Processor or Command, and then targets an Event or Error.

bounded_context "appointments" { event "appointment_added" { } } bounded_context "weather" { event "weather_predicted_for_appointment" { } } automation "add_weather_forecast" { processor "weather_processor" { from = [event.appointments.appointment_added] to = [command.add_weather_forecast] } command "add_weather_forecast" { to = [event.weather.weather_predicted_for_appointment] } scenario "forecast_is_added" { given { event = event.appointments.appointment_added } when { processor = processor.weather_processor } then { event = event.weather.weather_predicted_for_appointment } } }

Faded exercise: complete a State View

Fill in each ??? before opening the answer.

state_view "show_pet_details" { readmodel "pet_details" { question = ??? from = [???] to = [???] } screen "pet_details_screen" { actor = ??? } scenario "pet_details_loaded" { given { event = ??? } then { readmodel = ??? } } }
Answer bounded_context "pet_management" { event "pet_added" { } } actor "clinic_staff" { auth_required = true } state_view "show_pet_details" { readmodel "pet_details" { question = "What are the current details of this pet?" from = [event.pet_management.pet_added] to = [screen.pet_details_screen] } screen "pet_details_screen" { actor = actor.clinic_staff } scenario "pet_details_loaded" { given { event = event.pet_management.pet_added } then { readmodel = readmodel.pet_details } } }