Learn how to write integration tests against Azure Blob, Queue, and Table Storage using the Azurite emulator with Breakdance.
Breakdance provides first-class support for testing Azure Storage services using Azurite,
Microsoft’s official Azure Storage emulator. The CloudNimble.Breakdance.Azurite package handles all the complexity of
starting, configuring, and stopping Azurite instances during your test runs.
The simplest way to get started is to create a test class that inherits from AzuriteTestBase:
MyStorageTests.cs
Copy
Ask AI
using CloudNimble.Breakdance.Azurite;using Microsoft.VisualStudio.TestTools.UnitTesting;using System.Threading.Tasks;[TestClass]public class MyStorageTests : AzuriteTestBase{ private static AzuriteInstance _azurite; protected override AzuriteInstance Azurite => _azurite; [ClassInitialize] public static async Task ClassInit(TestContext ctx) { _azurite = await CreateAndStartInstanceAsync(new AzuriteConfiguration { Services = AzuriteServiceType.All, InMemoryPersistence = true, Silent = true }); } [ClassCleanup] public static async Task ClassCleanup() { await StopAndDisposeAsync(_azurite); _azurite = null; } [TestMethod] public async Task CanUploadBlob() { // Use the ConnectionString property to connect to Azurite var blobServiceClient = new BlobServiceClient(ConnectionString); var container = blobServiceClient.GetBlobContainerClient("test-container"); await container.CreateIfNotExistsAsync(); var blob = container.GetBlobClient("test-blob.txt"); await blob.UploadAsync(BinaryData.FromString("Hello, Azurite!")); Assert.IsTrue(await blob.ExistsAsync()); }}
Each test class owns its own static AzuriteInstance field. This design avoids cross-class pollution
where multiple test classes would share the same instance, which can cause port conflicts and test interference.
You can start only the services you need to reduce resource usage and startup time:
All Services
Blob Only
Queue Only
Multiple Services
Copy
Ask AI
var config = new AzuriteConfiguration{ Services = AzuriteServiceType.All // Blob, Queue, and Table};
Copy
Ask AI
var config = new AzuriteConfiguration{ Services = AzuriteServiceType.Blob};
Copy
Ask AI
var config = new AzuriteConfiguration{ Services = AzuriteServiceType.Queue};
Copy
Ask AI
var config = new AzuriteConfiguration{ Services = AzuriteServiceType.Blob | AzuriteServiceType.Queue};
Table-only mode (AzuriteServiceType.Table alone) is currently not supported due to an upstream bug in Azurite
where the table service reports incorrect port information. Use AzuriteServiceType.All if you need Table storage.
Once your test class is set up, AzuriteTestBase provides convenient properties for connecting to the services:
Copy
Ask AI
[TestMethod]public void AccessEndpoints(){ // Connection string for Azure SDK clients var connectionString = ConnectionString; // Individual endpoint URLs var blobUrl = BlobEndpoint; // e.g., "http://127.0.0.1:23456" var queueUrl = QueueEndpoint; // e.g., "http://127.0.0.1:23457" var tableUrl = TableEndpoint; // e.g., "http://127.0.0.1:23458" // Port numbers (useful for custom configurations) var blobPort = BlobPort; // e.g., 23456 var queuePort = QueuePort; // e.g., 23457 var tablePort = TablePort; // e.g., 23458}
Endpoint properties return null if that service was not requested in the configuration.
For example, if you set Services = AzuriteServiceType.Blob, then QueueEndpoint and TableEndpoint will be null.
If you have many test classes that need the same Azurite configuration, you can use assembly-level initialization:
AssemblySetup.cs
Copy
Ask AI
using CloudNimble.Breakdance.Azurite;using Microsoft.VisualStudio.TestTools.UnitTesting;using System.Threading.Tasks;[TestClass]public static class AssemblySetup{ public static AzuriteInstance SharedAzurite { get; private set; } [AssemblyInitialize] public static async Task AssemblyInit(TestContext ctx) { SharedAzurite = new AzuriteInstance(new AzuriteConfiguration { Services = AzuriteServiceType.All, InMemoryPersistence = true, Silent = true }); await SharedAzurite.StartAsync(); } [AssemblyCleanup] public static async Task AssemblyCleanup() { if (SharedAzurite != null) { await SharedAzurite.DisposeAsync(); SharedAzurite = null; } }}
Then reference it in your test classes:
Copy
Ask AI
[TestClass]public class MyTests : AzuriteTestBase{ protected override AzuriteInstance Azurite => AssemblySetup.SharedAzurite; [TestMethod] public void MyTest() { Assert.IsNotNull(BlobEndpoint); }}
When sharing an Azurite instance across test classes, be careful about test isolation.
Tests that create containers or queues may interfere with each other. Consider using unique
names (e.g., with Guid.NewGuid()) for test resources.
Each test class should have its own static AzuriteInstance field. If you’re sharing an instance,
use unique resource names in each test to avoid conflicts.
Slow startup times
Use InMemoryPersistence = true for faster startup
Only start the services you need (e.g., AzuriteServiceType.Blob instead of All)
Consider sharing an instance across test classes if appropriate