Have fun learning about Test-Driven Development with JitterTed's TDD Game

Live Coding Journal - Feb 16, 2026

Reflections, Learnings, and Mistakes from live coding my JitterTicket Event Sourcing application


Notes from Today’s Live Coding Session

Olive Tests = Test List?

Today I realized that the way I use Olive Tests, where the test fails as predicted, as I take small steps to get it to fail in a new, but still expected, way, is very much like Kent Beck’s Test List. However, Instead of spreading the steps across multiple tests, I’m spreading it across multiple assertions and using the idea of an Olive Test to allow me to know when to move forward to get the next assertion to pass.

Concert Started Processor is Doing its Job

When I ran all the tests for the first time since last week, I was initially confused by a test failure that checked available concerts in the sample data, where it found 9 instead of the 10 that the sample data populator creates. It turned out to be the ConcertStartedProcessor that I finished last week was doing its job by stopping ticket sales on one of the sample concert events, and therefore no longer appeared in the list of “available concerts”!

Reschedule Concert Use Case Complete

I finished the UI for “Reschedule Concert” and as is often the case, when I ran the application, it just worked. I did cheat a bit and reused an existing screen by adding a “reschedule” link to the “Concerts” view page, and after a Reschedule Concert is submitted, I redirect back to the Reschedule page instead of creating a new confirmation page. It’s not the way I’d do things if this were a production app, but this is an example learning app—despite its ever-increasing scope—so I’m OK with such shortcuts.

Design Aspects of Command Execution

I really like the way command method invocations are wrapped in a “unit of work”, like this code from the RescheduleConcertController’s POST handler:

copy
@PostMapping("/reschedule/{concertId}") public String rescheduleConcert(@PathVariable("concertId") String concertId, RescheduleForm rescheduleForm) { CommandExecutorFactory commandExecutorFactory = CommandExecutorFactory.create(concertEventStore); var command = commandExecutorFactory.wrapWithParams( (concert, reschedule) -> concert.rescheduleTo( reschedule.showDateTime(), reschedule.doorsTime())); Reschedule rescheduleParams = new Reschedule( rescheduleForm.newShowLocalDateTime(), rescheduleForm.newDoorsLocalTime()); command.execute(new ConcertId(UUID.fromString(concertId)), rescheduleParams); return "redirect:/reschedule/" + concertId; }

This code needs to be refactored, but the issue I’m struggling with is where the command creation (which is a stateless command object) would go. I don’t have a general design pattern for this kind of code, usually I have a “service” or “application” layer class that would handle the infrastructure work for multiple different commands. For example, see EnsembleService#joinAsParticipant()) in my Ensembler application. Note that even there I refactored to an “execute around” method (see line 179 in the same file), so that aspect isn’t new to me.

It seems like this controller method should map directly to one of those command objects, requiring some (“service”) class needs to provide a way to get the “Reschedule” command object, which would encapsulate the create() and wrapWithParams() that I’m doing above. Maybe the RescheduleForm would encapsulate the command, since it already has the information needed (new show date/time, etc.). I’ll start playing with some ideas for refactoring this on the next stream.

Deciders vs. Processors

After doing all this event-sourcing work with JitterTicket, I’m starting to get more precise about how I think and talk about the concepts. For example (at timestamp 3:04:50), I describe a Decider as something that takes existing State (projected from a series of events), makes a Decision using the state as input, and outputting an Event. I think of this as a Stateful Decider because it requires the input State in order to make a decision (am I allowing this command to succeed?). I haven’t (yet) come across a Stateless Decider, where the decision doesn’t require existing State, but that’s not to say it couldn’t exist. (If you know of an example, please share it with me!)

It’s possible a command that creates an entity (say, registering a new customer) is a Stateless Decider, but I think of it more explicitly as a Creator. However, if its creation has rules (e.g., customer email must be unique), then State is required (again from some projection, e.g., all active customer emails), so does that make it a Stateful Decider? From an event-sourcing point of view, creation is no different from any other event, so maybe it is?

A Stateless Processor on the other hand, takes an Event as input, and uses that to make a decision, and outputs a Command.

And I guess a Projector takes an event (or stream of events) and outputs a Projection, i.e., State. It might persist the previous state as a cache, but I see that as a Snapshot for optimization, something that Stateful Deciders could do as well, especially since a Stateful Decider is a Projection plus a Decider.

Next Steps

We’ll refactor the Reschedule command object and then create an “All Concert Aggregates” Projector to use when examining the underlying events with the event viewer. We need this because the current event viewer uses the “Available” concerts projection, which drops concerts that we might want to examine.

Join me on my next stream, which I usually do Monday through Thursday, starting at 20:00 UTC on Twitch: https://jitterted.stream.


Make Your Code More Testable™️

Don't miss out on ways to make your code more testable. Hear about new Refactoring techniques, improving the Test-Driven Development process, Hexagonal Architecture, and much more.

    We respect your privacy. Unsubscribe at any time.