Skip to main content

Definition

Assembly: CloudNimble.SimpleMessageBus.Breakdance.dll Namespace: CloudNimble.SimpleMessageBus.Breakdance Inheritance: System.Object

Syntax

CloudNimble.SimpleMessageBus.Breakdance.TestableMessagePublisher

Summary

A test double for IMessagePublisher that captures published messages for assertions. Used in testing scenarios to verify that expected messages were published correctly.

Remarks

The TestableMessagePublisher is designed for unit and integration testing of message publishing scenarios. It implements the IMessagePublisher interface but instead of sending messages to actual queues, it captures them in memory for verification. This enables testing of message publishing behavior without requiring real message queue infrastructure. Key testing features:
  • Captures all published messages for assertion
  • Supports configurable actions to simulate publish behavior
  • Provides methods to reset state between tests
  • Maintains message order for sequence verification
This class is part of the “Breakdance” testing utilities, named after the dance style that emphasizes breaking conventional patterns - just like how test doubles break the normal execution flow for testing.

Examples

// Basic usage in a unit test
var publisher = new TestableMessagePublisher();
var messageHandler = new OrderHandler(publisher);

// Execute the code under test
await messageHandler.ProcessOrder(orderId);

// Verify the expected messages were published
Assert.AreEqual(2, publisher.PublishedMessages.Count);
Assert.IsInstanceOfType(publisher.PublishedMessages[0], typeof(InventoryReservedMessage));
Assert.IsInstanceOfType(publisher.PublishedMessages[1], typeof(PaymentProcessedMessage));

// Advanced scenario with custom action
var publisher = new TestableMessagePublisher();
publisher.SetAction((message, isSystem) =>
{
    // Simulate behavior like throwing exceptions for certain message types
    if (message is ProblemMessage)
        throw new InvalidOperationException("Simulated failure");
});

// Test exception handling in your code
await Assert.ThrowsExceptionAsync<InvalidOperationException>(() =>
    messageHandler.ProcessProblemScenario());

Constructors

.ctor

Initializes a new instance of the TestableMessagePublisher class. Creates an empty publisher with no published messages or configured actions.

Syntax

public TestableMessagePublisher()

.ctor Inherited

Inherited from object

Syntax

public Object()

Properties

PublishedMessages

Gets a read-only list of all messages that have been published via this publisher. This collection can be used in test assertions to verify published message content.

Syntax

public System.Collections.Generic.IReadOnlyList<CloudNimble.SimpleMessageBus.Core.IMessage> PublishedMessages { get; }

Property Value

Type: System.Collections.Generic.IReadOnlyList<CloudNimble.SimpleMessageBus.Core.IMessage> A read-only list containing all messages published through this publisher in the order they were published. The collection is empty when the publisher is first created or after TestableMessagePublisher.ClearMessages is called.

Examples

// Verify message count and types
Assert.AreEqual(3, publisher.PublishedMessages.Count);
Assert.IsTrue(publisher.PublishedMessages.Any(m =&gt; m is OrderCreatedMessage));

// Verify specific message content
var orderMessage = publisher.PublishedMessages.OfType&lt;OrderCreatedMessage&gt;().First();
Assert.AreEqual("ORD-001", orderMessage.OrderNumber);

// Verify message sequence
Assert.IsInstanceOfType(publisher.PublishedMessages[0], typeof(OrderCreatedMessage));
Assert.IsInstanceOfType(publisher.PublishedMessages[1], typeof(InventoryReservedMessage));
Assert.IsInstanceOfType(publisher.PublishedMessages[2], typeof(PaymentProcessedMessage));

Remarks

This property provides access to all messages captured during testing. Messages are stored in publication order, allowing verification of both message content and sequence. The returned collection is read-only to prevent external modification of the test state. Use this property in test assertions to verify:
  • The correct number of messages were published
  • The right message types were published
  • Messages contain expected data
  • Messages were published in the correct order

Methods

ClearMessages

Clears all published messages from the internal collection. Use this method to reset the state between tests.

Syntax

public void ClearMessages()

Examples

[Test]
public async Task Should_Publish_Order_Message()
{
    // Arrange
    publisher.ClearMessages(); // Ensure clean state
    var order = new CreateOrderCommand { ProductId = "PROD-001" };

    // Act
    await orderService.CreateOrderAsync(order);

    // Assert
    Assert.AreEqual(1, publisher.PublishedMessages.Count);
    Assert.IsInstanceOfType(publisher.PublishedMessages[0], typeof(OrderCreatedMessage));
}

Remarks

This method is typically called in test setup or teardown to ensure each test starts with a clean state. After calling this method, the TestableMessagePublisher.PublishedMessages collection will be empty until new messages are published. This prevents test interference where one test’s published messages affect another test’s assertions.

Equals Inherited Virtual

Inherited from object

Syntax

public virtual bool Equals(object obj)

Parameters

NameTypeDescription
objobject?-

Returns

Type: bool

Equals Inherited

Inherited from object

Syntax

public static bool Equals(object objA, object objB)

Parameters

NameTypeDescription
objAobject?-
objBobject?-

Returns

Type: bool

GetHashCode Inherited Virtual

Inherited from object

Syntax

public virtual int GetHashCode()

Returns

Type: int

GetType Inherited

Inherited from object

Syntax

public System.Type GetType()

Returns

Type: System.Type

MemberwiseClone Inherited

Inherited from object

Syntax

protected internal object MemberwiseClone()

Returns

Type: object

PublishAsync

Implements the IMessagePublisher interface method by capturing the published message for later assertion and optionally invoking a configured action.

Syntax

public System.Threading.Tasks.Task PublishAsync(CloudNimble.SimpleMessageBus.Core.IMessage message, bool isSystemGenerated = false)

Parameters

NameTypeDescription
messageCloudNimble.SimpleMessageBus.Core.IMessageThe message to publish.
isSystemGeneratedboolIndicates whether the message is system-generated.

Returns

Type: System.Threading.Tasks.Task A completed task.

Exceptions

ExceptionDescription
ExceptionMay throw exceptions if a custom action configured via Boolean}) throws.

Examples

// Direct usage (though typically called by code under test)
var message = new OrderCreatedMessage { OrderNumber = "ORD-001" };
await publisher.PublishAsync(message, isSystemGenerated: false);

// Verify it was captured
Assert.AreEqual(1, publisher.PublishedMessages.Count);
Assert.AreSame(message, publisher.PublishedMessages[0]);

Remarks

This method implements the core functionality of the test double by:
  1. Adding the message to the internal collection for later verification
  2. Invoking any configured action (if set via Boolean}))
  3. Returning a completed task to satisfy the async interface
Unlike real message publishers, this method does not actually send messages to any queue. It completes synchronously and never throws exceptions unless a custom action is configured to do so.

ReferenceEquals Inherited

Inherited from object

Syntax

public static bool ReferenceEquals(object objA, object objB)

Parameters

NameTypeDescription
objAobject?-
objBobject?-

Returns

Type: bool

SetAction

Sets an action to be executed when a message is published.

Syntax

public void SetAction(System.Action<CloudNimble.SimpleMessageBus.Core.IMessage, bool> onPublish)

Parameters

NameTypeDescription
onPublishSystem.Action<CloudNimble.SimpleMessageBus.Core.IMessage, bool>The action to execute when PublishAsync is called.
The action receives the published message and the isSystemGenerated flag.

Examples

// Simulate publishing failures for certain message types
publisher.SetAction((message, isSystem) =&gt;
{
    if (message is CriticalMessage)
        throw new InvalidOperationException("Publishing service unavailable");
});

// Simulate side effects like logging or notifications
publisher.SetAction((message, isSystem) =&gt;
{
    if (isSystem)
        systemMessageCount++;
    logger.LogInformation("Published {MessageType}", message.GetType().Name);
});

// Remove the action
publisher.SetAction(null);

Remarks

This method allows customization of the publisher’s behavior during testing. The configured action is invoked after the message is added to the TestableMessagePublisher.PublishedMessages collection, allowing for simulation of various publishing scenarios such as failures, delays, or side effects. Setting this to null removes any previously configured action. The action is optional and publishing will work normally even without it being set.

ToString Inherited Virtual

Inherited from object

Syntax

public virtual string ToString()

Returns

Type: string?
  • CloudNimble.SimpleMessageBus.Publish.IMessagePublisher