Testing the Bus
Before we cover Event publishing from the Bus, let’s write a test to make sure the Send<T>(T command)
method does what it should, i.e. allow us to send a Command into the Bus to have the appropriate Command Handlers call their Handle
methods with the Command as parameter.
We can use the Specification
class that we wrote in our discussion of testing Event Sourced Aggregate Roots here. We’ll tweak it a bit so that we can test the Bus in the context of a stub TestCommand
and a mock TestCommandHandler
.
We start by adding additional instance variables to hold our mock implementations of Command
and ICommandHandler<Command>
:
public class When_sending_a_command_to_the_fakebus_with_a_single_command_handler : Specification<TestAggregateRoot, TestCommand> {
private readonly FakeBus _bus;
private TestCommandHandler _handler;
private TestCommand _command;
...
}
Then we’ll instantiate the FakeBus
and register a TestCommandHandler
to it:
public class When_sending_a_command_to_the_fakebus_with_a_single_command_handler : Specification<TestAggregateRoot, TestCommand> {
private readonly FakeBus _bus;
private TestCommandHandler _handler;
private TestCommand _command;
public When_sending_a_command_to_the_fakebus_with_a_single_command_handler() {
_bus = new FakeBus();
_bus.RegisterHandler<TestCommand>(_handler.Handle);
}
...
}
Here’s what TestCommandHandler
looks like:
public class TestCommandHandler : ICommandHandler<TestCommand> {
public List<Guid> CommandIds { get; }
public TestCommandHandler() {
CommandIds = new List<Guid>();
}
public void Handle(TestCommand command) {
CommandIds.Add(command.Id);
}
}
So the Command Handler simply keeps a list of Command Ids that are sent to it, signifying that it has handled them. We can assert that the Id of a Command that we send to the Bus is added to this list of Ids, therefore verifying that the Bus successfully hands the message to its handler(s).
When()
and CommandHandler()
are tweaked to assign the TestCommand
and TestCommandHandler
properties:
public class When_sending_a_command_to_the_fakebus_with_a_single_command_handler : Specification<TestAggregateRoot, TestCommand> {
private readonly FakeBus _bus;
private TestCommandHandler _handler;
private TestCommand _command;
public When_sending_a_command_to_the_fakebus_with_a_single_command_handler() {
_bus = new FakeBus();
_bus.RegisterHandler<TestCommand>(_handler.Handle);
}
protected override TestCommand When() {
_command = new TestCommand(Guid.NewGuid());
return _command;
}
protected override ICommandHandler<TestCommand> CommandHandler() {
_handler = new TestCommandHandler();
return _handler;
}
...
}
Finally, we verify that the Bus passed our Command to the Command Handler that was registered to it. Simply by verifying that the Command Handler added the Command’s Id to its internal collection:
[Then]
public void Then_handle_method_is_invoked_on_command_handler() {
_handler.CommandIds.First().Should().Be(_command.Id);
}
Now that we’ve spent some time getting familiar with what the Bus should do when a Command is sent to it, let’s look at how Events are published through it. Publishing Events through the Bus leads us to an important component of our Read Model: Projections. Stay tuned.
I will be releasing most of this content only to subscribers. Make sure you sign up by clicking the big red button!
Related Posts:
- Sending Commands to the Bus
- The Bus
- The Read Model
- An Executable Specification
- Testing an Event Sourced Aggregate Root
- Aggregate Event Persistence
- Event Store
- Command Handlers
- Implementing an Event Sourced Aggregate
- Design Level Continued
- Complexity and Cost
- Design Level EventStorming
- People and Commands
- Hotspots
- Domain Discoveries
- Big Picture EventStorming
- The Domain - First Pop Coffee Company
- More Efficient Domain Modeling with EventStorming
- Where do you find resources for learning DDD, CQRS, Event Sourcing, and EventStorming?
- Has the code devolved into a big ball of mud?… What can you do about it?
- A Better Way to Project Domain Entities into DTOs
- Exposing IQueryable in a CQRS Query Stack
- A Pattern to Decouple your Aggregates from their Clients
- Erlang-style Supervisors in C# with Akka.NET and the Actor Model