Excalibur.Dispatch.Testing.Shouldly
3.0.0-alpha.43
This is a prerelease version of Excalibur.Dispatch.Testing.Shouldly.
dotnet add package Excalibur.Dispatch.Testing.Shouldly --version 3.0.0-alpha.43
NuGet\Install-Package Excalibur.Dispatch.Testing.Shouldly -Version 3.0.0-alpha.43
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.Shouldly" Version="3.0.0-alpha.43" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Excalibur.Dispatch.Testing.Shouldly" Version="3.0.0-alpha.43" />
<PackageReference Include="Excalibur.Dispatch.Testing.Shouldly" />
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.Shouldly --version 3.0.0-alpha.43
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Excalibur.Dispatch.Testing.Shouldly, 3.0.0-alpha.43"
#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.Shouldly@3.0.0-alpha.43
#: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.Shouldly&version=3.0.0-alpha.43&prerelease
#tool nuget:?package=Excalibur.Dispatch.Testing.Shouldly&version=3.0.0-alpha.43&prerelease
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Excalibur.Dispatch.Testing.Shouldly
Shouldly assertion extensions for Excalibur testing. Provides fluent, readable assertions for message dispatch verification.
Installation
dotnet add package Excalibur.Dispatch.Testing.Shouldly
Requires:
Excalibur.Dispatch.Testing(core test infrastructure)Shouldly(assertion library)
Features
- 9 extension methods for IDispatchedMessageLog, InMemoryTransportSender, InMemoryTransportReceiver
- Fluent assertions aligned with Shouldly conventions
- Clear failure messages that describe what was expected vs. what actually happened
- Same namespace as core Testing package - no extra
usingneeded
Quick Start
using Excalibur.Dispatch.Testing; // Extensions auto-discovered
// Arrange
var harness = new DispatchTestHarness();
harness.ConfigureDispatch(d => d.AddHandlersFromAssembly(typeof(MyHandler).Assembly));
// Act
await harness.Dispatcher.DispatchAsync(new OrderCreated { Id = 123 });
// Assert - fluent Shouldly extensions
harness.Dispatched.ShouldHaveDispatched<OrderCreated>();
harness.Dispatched.ShouldNotHaveDispatched<OrderCancelled>();
IDispatchedMessageLog Extensions
Assert on messages captured during pipeline execution.
// Verify message was dispatched
harness.Dispatched.ShouldHaveDispatched<OrderCreated>();
// Verify message was NOT dispatched
harness.Dispatched.ShouldNotHaveDispatched<OrderCancelled>();
// Verify exact count of a message type
harness.Dispatched.ShouldHaveDispatched<OrderCreated>(expectedCount: 2);
// Verify total dispatched count
harness.Dispatched.ShouldHaveDispatchedCount(3);
InMemoryTransportSender Extensions
Assert on transport send operations.
var sender = new InMemoryTransportSender();
// Send messages
await sender.SendAsync(new TransportMessage(...), CancellationToken.None);
await sender.SendAsync(new TransportMessage(...), CancellationToken.None);
await sender.SendAsync(new TransportMessage(...), CancellationToken.None);
// Verify send count
sender.ShouldHaveSent(3);
// Verify message was sent
sender.ShouldHaveSent(message);
// Verify message NOT sent
sender.ShouldNotHaveSent(message);
InMemoryTransportReceiver Extensions
Assert on transport receive operations.
var receiver = new InMemoryTransportReceiver();
// Queue and process messages
receiver.QueueMessage(new TransportMessage(...));
var message = await receiver.ReceiveAsync(CancellationToken.None);
await receiver.AcknowledgeAsync(message.MessageId, CancellationToken.None);
// Verify acknowledgments
receiver.ShouldHaveAcknowledged(1);
receiver.ShouldHaveAcknowledged(message.MessageId);
// Verify rejections
receiver.ShouldHaveRejected(0);
Complete Example
public class OrderWorkflowTests : IAsyncDisposable
{
private readonly DispatchTestHarness _harness = new();
private readonly InMemoryTransportSender _sender = new();
public OrderWorkflowTests()
{
_harness.ConfigureServices(services =>
{
services.AddSingleton<ITransportSender>(_sender);
});
_harness.ConfigureDispatch(d =>
{
d.AddHandlersFromAssembly(typeof(OrderHandler).Assembly);
});
}
[Fact]
public async Task CreateOrder_ShouldPublishEvent()
{
// Arrange
var command = new CreateOrderCommand { ProductId = 123, Quantity = 2 };
// Act
await _harness.Dispatcher.DispatchAsync(command, CancellationToken.None);
// Assert - fluent Shouldly assertions
_harness.Dispatched.ShouldHaveDispatched<OrderCreated>(
evt => evt.ProductId == 123 && evt.Quantity == 2);
_sender.ShouldHaveSent(1);
_sender.ShouldHaveSent(msg =>
msg.Body.Contains("OrderCreated") && msg.Body.Contains("123"));
}
[Fact]
public async Task CancelOrder_ShouldNotPublishCreatedEvent()
{
// Arrange
var command = new CancelOrderCommand { OrderId = 456 };
// Act
await _harness.Dispatcher.DispatchAsync(command, CancellationToken.None);
// Assert
_harness.Dispatched.ShouldNotHaveDispatched<OrderCreated>();
_harness.Dispatched.ShouldHaveDispatched<OrderCancelled>();
}
public async ValueTask DisposeAsync()
{
await _harness.DisposeAsync();
}
}
Extension Methods Reference
| Method | Target | Description |
|---|---|---|
ShouldHaveDispatched<T>() |
IDispatchedMessageLog | Verify message of type T was dispatched |
ShouldHaveDispatched<T>(predicate) |
IDispatchedMessageLog | Verify message matching predicate |
ShouldHaveDispatched(message) |
IDispatchedMessageLog | Verify specific message instance |
ShouldNotHaveDispatched<T>() |
IDispatchedMessageLog | Verify message of type T was NOT dispatched |
ShouldHaveSent(count) |
InMemoryTransportSender | Verify exact send count |
ShouldHaveSent(message) |
InMemoryTransportSender | Verify specific message sent |
ShouldNotHaveSent(message) |
InMemoryTransportSender | Verify message NOT sent |
ShouldHaveAcknowledged(count) |
InMemoryTransportReceiver | Verify acknowledgment count |
ShouldHaveRejected(count) |
InMemoryTransportReceiver | Verify rejection count |
Failure Messages
Shouldly extensions provide clear failure messages:
// Assertion failure
harness.Dispatched.ShouldHaveDispatched<OrderCreated>();
// Output:
// harness.Dispatched
// should have dispatched
// Excalibur.Dispatch.Messages.OrderCreated
// but did not.
// Dispatched messages:
// [0] Excalibur.Dispatch.Messages.OrderUpdated
// [1] Excalibur.Dispatch.Messages.OrderCancelled
Documentation
License
MIT
| Product | Versions 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.
-
net10.0
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Excalibur.Dispatch.Testing (>= 3.0.0-alpha.43)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- Shouldly (>= 4.3.0)
- System.Threading.RateLimiting (>= 10.0.0)
-
net8.0
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Excalibur.Dispatch.Testing (>= 3.0.0-alpha.43)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- Shouldly (>= 4.3.0)
- System.Diagnostics.DiagnosticSource (>= 10.0.0)
- System.IO.Pipelines (>= 10.0.0)
- System.Text.Json (>= 10.0.0)
- System.Threading.Channels (>= 10.0.0)
- System.Threading.RateLimiting (>= 10.0.0)
-
net9.0
- CloudNative.CloudEvents (>= 2.8.0)
- CloudNative.CloudEvents.SystemTextJson (>= 2.8.0)
- Cronos (>= 0.11.1)
- Excalibur.Dispatch.Testing (>= 3.0.0-alpha.43)
- Medo.Uuid7 (>= 1.4.0)
- MemoryPack (>= 1.21.4)
- Microsoft.ApplicationInsights (>= 2.23.0)
- Microsoft.AspNetCore.Authorization (>= 9.0.9)
- Microsoft.Extensions.Configuration (>= 10.0.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Http (>= 10.0.0)
- Microsoft.Extensions.Logging (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.ObjectPool (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.0)
- Microsoft.Extensions.Options.DataAnnotations (>= 10.0.0)
- Shouldly (>= 4.3.0)
- System.Diagnostics.DiagnosticSource (>= 10.0.0)
- System.IO.Pipelines (>= 10.0.0)
- System.Text.Json (>= 10.0.0)
- System.Threading.Channels (>= 10.0.0)
- System.Threading.RateLimiting (>= 10.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0-alpha.43 | 0 | 3/16/2026 |
| 3.0.0-alpha.42 | 0 | 3/16/2026 |
| 3.0.0-alpha.41 | 0 | 3/16/2026 |
| 3.0.0-alpha.33 | 27 | 3/15/2026 |
| 3.0.0-alpha.31 | 25 | 3/15/2026 |
| 3.0.0-alpha.26 | 37 | 3/5/2026 |
| 3.0.0-alpha.19 | 46 | 2/26/2026 |