- TrafficLight Experiment.
- Advantage of DDD approach to the problem
- Traffic Light, say goodbye to public properties
It is a long time I did not post about simple Traffic Light experiment. I’ve ended with a super simple Domain with no Getters and no Setters, but there is still something I really do not like about that sample and it is represented by this test.
This test is quite ugly and it requires some initialization code, contained in the constructor of the test class.
The bad part about this code is that I want to test this situation: when both traffic light are in red state, only one of them can become green after a given amount of time passed. The awful part about this test is how I setup the fixture; to bring both the Traffic Light in the Red state, I need to create the CrossRoadFactory in the constructor of the test (this is because all tests share this common initialization), then I need to call Tick() several time simulating passing time and moving the system from the initial status to the status that represents the fixture (both light red).
This test is simply wrong, because if if fails you cannot tell if the failure is caused by the initialization code or the real part of the domain logic you want to test, because I’m actually exercising the SUT until it reach the status I want to test with my unit test and this can cause a failure in the Fixture. This is done because if the Traffic Light has no public properties and it is not possible to manipulate the status directly in the test.
To simplify the test I need a way to change the status of a Traffic Light, so I can simply fixture creation and the obvious solution is to use Event Sourcing. I do not want to evolve the Traffic Light to a full Event Sourcing enabled domain, but I wish to verify if having the ability to reconstruct the state of a Domain Object from domain events he raised in the past can solve my test smell. I decided to add a constructor on the TrafficLight domain class that permits to create an instance from a sequence of Domain Events.
This is really primitive, it is really far from being a real entity based on Event Sourcing, but the key concept is, I want to be able to reconstruct the private state of an entity simply passing a series of domain events that he raised in the past. Now the previous test can be modified to make it really simpler:
Now I’m able to create two traffic light passing a ChangedLightStatus event that bring the Traffic Light to the status requested by the fixture, then I can create the CrossRoad class passing two TrafficLightCreated domain events and this is all the code I need to setup the fixture of my test. Now I can simulate that one second is passed, call Tick() function on the CrossRoad and verify that only one Domain Event is raised , because only one Traffic Light Should have changed the value of the light from Red to Green.
Even with this super simple example you can understand that Event Sourcing simplify your tests , because they give you the ability to recreate a specific state of the domain under test from a stream of Domain Events.