Skip to main content
Version: v1.3.0

Service bus

The Arcus.Testing.Messaging.ServiceBus package provides test fixtures related to Azure Service Bus. By using the common testing practice 'clean environment', it provides a temporary Topic (subscription) and queue.

Installation

The following functionality is available when installing this package:

PM> Install-Package -Name Arcus.Testing.Messaging.ServiceBus

Temporary topic

The TemporaryTopic provides a solution when the integration test requires an Azure Service Bus topic during the test run. A topic is created upon the setup of the test fixture and is deleted again when the test fixture is disposed.

✨ Only when the test fixture was responsible for creating the topic, will the topic be deleted upon the fixture's disposal. This follows the 'clean environment' testing principle that describes that after the test run, the same state should be achieved as before the test run.

using Arcus.Testing;

await using var topic = await TemporaryTopic.CreateIfNotExistsAsync(
"<fully-qualified-namespace>", "<topic-name>", logger);

⚡ Uses by default the DefaultAzureCredential but other type of authentication mechanisms are supported with overloads.

Adding subscriptions to the topic can also be done via the test fixture. It always makes sure that any added subscriptions are deleted again afterwards.

using Arcus.Testing;

await using TemporaryTopic topic = ...

await topic.AddSubscriptionAsync("<subscription-name>");

Customization

The TemporaryTopic allows testers to configure setup/teardown operations on any messages that were on the topic subscriptions (or the topic itself) at the time of setup/teardown. This follows the 'clean environment' testing principle.

using Arcus.Testing;

await TemporaryTopic.CreateIfNotExistsAsync(..., options =>
{
// Options related to when the test fixture is set up.
// ---------------------------------------------------

// Change the default topic-creation behavior.
options.OnSetup.CreateTopicWith((CreateTopicOptions opt) => ...);

// (Default) leave any existing messages on all the topic subscriptions.
options.OnSetup.LeaveExistingMessages();

// Dead-letter any existing messages on all the topic subscriptions.
options.OnSetup.DeadLetterMessages(); // 💡 Max wait time default 5 seconds.
options.OnSetup.DeadLetterMessages(TimeSpan.FromSeconds(10));
options.OnSetup.DeadLetterMessages((ServiceBusReceivedMessage msg) =>
{
// ⚡ Multiple calls will be aggregated.
// ⚡ Can be used in combination with other complete/dead-letter operations.
return msg.ApplicationProperties.ContainsKey("<key>");
});

// Complete any existing messages on all the topic subscriptions.
options.OnSetup.CompleteMessages(); // 💡 Max wait time default 5 seconds.
options.OnSetup.CompleteMessages(TimeSpan.FromSeconds(10));
options.OnSetup.CompleteMessages((ServiceBusReceivedMessage msg) =>
{
// ⚡ Multiple calls will be aggregated.
// ⚡ Can be used in combination with other complete/dead-letter operations.
return msg.ApplicationProperties.ContainsKey("<key>");
});

// Options related to when the test fixture is teared down.
// --------------------------------------------------------

// (Default) Dead-letter any lingering messages on all the topic subscriptions.
options.OnTeardown.DeadLetterMessages(); // 💡 Max wait time default 5 seconds.
options.OnTeardown.DeadLetterMessages(TimeSpan.FromSeconds(10));
options.OnTeardown.DeadLetterMessages((ServiceBusReceivedMessage msg) =>
{
// ⚡ Multiple calls will be aggregated.
// ⚡ Can be used in combination with other complete/dead-letter operations.
return msg.ApplicationProperties.ContainsKey("<key>");
});

// Complete any lingering messages on all the topic subscriptions.
options.OnTeardown.CompleteMessages(); // 💡 Max wait time default 5 seconds.
options.OnTeardown.CompleteMessages(TimeSpan.FromSeconds(10));
options.OnTeardown.CompleteMessages((ServiceBusReceivedMessage msg) =>
{
// ⚡ Multiple calls will be aggregated.
// ⚡ Can be used in combination with other complete/dead-letter operations.
return msg.ApplicationProperties.ContainsKey("<key>");
});
});

Peek for messages

The TemporaryTopic is equipped with a message filtering system that allows testers to search for messages during the lifetime of the test fixture. This can be useful to verify the current state of a topic, or as a test assertion to verify Service bus-related implementations.

using Arcus.Testing;

await using TemporaryTopic topic = ...

IEnumerable<ServiceBusReceivedMessage> messages =
await topic.MessagesOn("<subscription-name>")

// Get subset messages currently on the topic subscription.
.Where(msg => msg.ApplicationProperties.ContainsKey("<my-key>"))
.Where(msg => msg.ContentType == "application/json")

// Get messages only from the dead-letter sub-queue.
.FromDeadLetter()

// Get only a number of messages (default: 100).
.Take(10)

// Start peeking for messages.
.ToListAsync();