Excalibur.Dispatch.Testing 3.0.0-alpha.33

This is a prerelease version of Excalibur.Dispatch.Testing.
dotnet add package Excalibur.Dispatch.Testing --version 3.0.0-alpha.33
                    
NuGet\Install-Package Excalibur.Dispatch.Testing -Version 3.0.0-alpha.33
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Excalibur.Dispatch.Testing" Version="3.0.0-alpha.33" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Excalibur.Dispatch.Testing" Version="3.0.0-alpha.33" />
                    
Directory.Packages.props
<PackageReference Include="Excalibur.Dispatch.Testing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Excalibur.Dispatch.Testing --version 3.0.0-alpha.33
                    
#r "nuget: Excalibur.Dispatch.Testing, 3.0.0-alpha.33"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Excalibur.Dispatch.Testing@3.0.0-alpha.33
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Excalibur.Dispatch.Testing&version=3.0.0-alpha.33&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Excalibur.Dispatch.Testing&version=3.0.0-alpha.33&prerelease
                    
Install as a Cake Tool

Excalibur.Dispatch.Testing

Test infrastructure for the Dispatch messaging pipeline. Provides a lightweight, framework-agnostic test harness with message tracking, fluent builders, and spy middleware.

Installation

dotnet add package Excalibur.Dispatch.Testing

Features

  • DispatchTestHarness - Lazy-build DI container for testing Dispatch pipelines
  • MessageContextBuilder - Fluent API for creating test message contexts
  • IDispatchedMessageLog/DispatchedMessageLog - In-memory message tracking
  • TestTrackingMiddleware - Spy middleware for observing pipeline execution
  • Framework-agnostic - Works with xUnit, NUnit, MSTest, or any test framework

Quick Start

// Create harness and configure pipeline
var harness = new DispatchTestHarness();
harness.ConfigureDispatch(d => d.AddHandlersFromAssembly(typeof(MyHandler).Assembly));

// Dispatch messages
await harness.Dispatcher.DispatchAsync(new MyCommand(), CancellationToken.None);

// Verify dispatched messages
harness.Dispatched.Count.ShouldBe(1);
harness.Dispatched.All[0].Message.ShouldBeOfType<MyCommand>();

// Clean up
await harness.DisposeAsync();

DispatchTestHarness

Lazy-build service provider that accumulates DI registrations and builds the container on first access.

var harness = new DispatchTestHarness();

// Configure services (accumulates until first access)
harness.ConfigureServices(services =>
{
    services.AddSingleton<IMyService, MyService>();
});

// Configure Dispatch pipeline
harness.ConfigureDispatch(d =>
{
    d.AddHandlersFromAssembly(typeof(MyHandler).Assembly);
    d.AddMiddleware<ValidationMiddleware>();
});

// ServiceProvider built on first property access
var dispatcher = harness.Dispatcher;
var log = harness.Dispatched;

MessageContextBuilder

Fluent API for creating test message contexts with custom properties, cancellation tokens, and metadata.

var context = new MessageContextBuilder()
    .WithMessage(new MyCommand { Id = 123 })
    .WithUserId("user-123")
    .WithTenantId("tenant-42")
    .WithCorrelationId("corr-abc")
    .Build();

await dispatcher.DispatchAsync(context);

IDispatchedMessageLog

In-memory log that captures all messages dispatched during tests.

// Access via harness
var log = harness.Dispatched;

// Query dispatched messages
log.Count.ShouldBe(3);
log.Select<OrderCreated>().Count.ShouldBe(1);
log.All.Count(m => m.Message is OrderUpdated).ShouldBe(2);

// Clear log between test phases
log.Clear();

TestTrackingMiddleware

Spy middleware automatically registered by DispatchTestHarness. Captures all messages passing through the pipeline.

// Automatically registered - no manual setup needed
var harness = new DispatchTestHarness();
harness.ConfigureDispatch(d => d.AddHandlersFromAssembly(typeof(MyHandler).Assembly));

// Middleware captures messages as they flow through pipeline
await harness.Dispatcher.DispatchAsync(new MyCommand());

// Verify via Dispatched log
harness.Dispatched.All.ShouldContain(m => m.Message is MyCommand);

Integration with Testing.Shouldly

For fluent assertions, add the companion package:

dotnet add package Excalibur.Dispatch.Testing.Shouldly
// Fluent Shouldly extensions
harness.Dispatched.ShouldHaveDispatched<OrderCreated>();
harness.Dispatched.ShouldNotHaveDispatched<OrderCancelled>();
sender.ShouldHaveSent(3);
receiver.ShouldHaveAcknowledged(2);

See Excalibur.Dispatch.Testing.Shouldly for details.

Complete Example

public class OrderHandlerTests : IAsyncDisposable
{
    private readonly DispatchTestHarness _harness = new();

    public OrderHandlerTests()
    {
        _harness.ConfigureServices(services =>
        {
            services.AddSingleton<IOrderRepository, InMemoryOrderRepository>();
        });

        _harness.ConfigureDispatch(d =>
        {
            d.AddHandlersFromAssembly(typeof(OrderHandler).Assembly);
        });
    }

    [Fact]
    public async Task CreateOrder_ShouldDispatchOrderCreatedEvent()
    {
        // Arrange
        var command = new CreateOrderCommand { ProductId = 123, Quantity = 2 };

        // Act
        await _harness.Dispatcher.DispatchAsync(command, CancellationToken.None);

        // Assert
        _harness.Dispatched.Count.ShouldBe(1);
        var evt = _harness.Dispatched.All[0].Message.ShouldBeOfType<OrderCreated>();
        evt.ProductId.ShouldBe(123);
        evt.Quantity.ShouldBe(2);
    }

    public async ValueTask DisposeAsync()
    {
        await _harness.DisposeAsync();
    }
}

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Excalibur.Dispatch.Testing:

Package Downloads
Excalibur.Dispatch.Testing.Shouldly

Shouldly assertion extensions for the Excalibur testing utilities. Provides fluent assertions for DispatchTestHarness message logs, InMemoryTransportSender, InMemoryTransportReceiver, and InMemoryTransportSubscriber.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0-alpha.33 22 3/15/2026
3.0.0-alpha.31 21 3/15/2026
3.0.0-alpha.26 41 3/5/2026
3.0.0-alpha.19 47 2/26/2026