How to make integration test for Azure Storage in C# – Part 2

In the first part and previous article, we covered how to install Azurite, an Azure Storage Emulator. We have also learned how to fire up a local emulator for testing.

Now we will build a small storage app that can do basic stuff like, read, write and delete, and then we will test it with Azurite.

First of all, I create an empty solution in Visual Studio 2022 and call it AzureBlobStorageApp. Then I will create my first library project and call it AzureBlobStorageApp .

I add Azure.Storage.Blobs NuGet package to my project.

<ItemGroup>
  <PackageReference Include="Azure.Storage.Blobs" Version="12.10.0" />
</ItemGroup>

Now let’s create a class AzureBlobStorage.cs with a constructor that takes the connection string and container name.

public AzureBlobStorage(string connectionString, string container)
{
    _blobContainerClient = new BlobContainerClient(connectionString, container);
    _blobContainerClient.CreateIfNotExists();
}

We will create 3 methods that Read, Create and Delete text files.

public async Task<string> ReadTextFile(string filename)
{
    var blob = _blobContainerClient.GetBlobClient(filename);
    if (!await _blobContainerClient.ExistsAsync()) return string.Empty;
    var reading = await blob.DownloadStreamingAsync();
    StreamReader reader = new StreamReader(reading.Value.Content);
    return await reader.ReadToEndAsync();
}

public async Task CreateTextFile(string filename, byte[] data)
{
    var blob = _blobContainerClient.GetBlobClient(filename);
    await using var ms = new MemoryStream(data, false);
    await blob.UploadAsync(ms, CancellationToken.None);
}

public async Task DeleteTextFile(string filename)
{
    var blobClient = _blobContainerClient.GetBlobClient(filename);
    await blobClient.DeleteAsync();
}

Now we create a new xUnit test project and call it AzureBlobStorageApp.UnitTests

Check and eventually add the following dependencies, and of course, add reference to our AzureBlobStorageApp project as well.

<ItemGroup>
  <PackageReference Include="Azure.Storage.Blobs" Version="12.10.0" />
  <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
  <PackageReference Include="xunit" Version="2.4.1" />
  <PackageReference Include="xunit.console" Version="2.4.1" />
  <PackageReference Include="xunit.runner.console" Version="2.4.1">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
  </PackageReference>
  <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
  </PackageReference>
</ItemGroup>

<ItemGroup>
  <ProjectReference Include="..\AzureBlobStorageApp\AzureBlobStorageApp.csproj" />
</ItemGroup>

Let’s create a class AzureBlobStorageUnitTests with variable declaration and constructor:

private const string Content = "Some Data inside file Content";

private const string DefaultEndpointsProtocol = "http";
private const string AccountName = "devstoreaccount1";
private const string AccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
private const string BlobEndpoint = "http://127.0.0.1:10000/devstoreaccount1";
private const string ConnectionString = $"DefaultEndpointsProtocol={DefaultEndpointsProtocol};AccountName={AccountName};AccountKey={AccountKey};BlobEndpoint={BlobEndpoint};";

private const string Container = "container-1";
public AzureBlobStorageUnitTests()
{
    _azureBlobStorage = new AzureBlobStorage(ConnectionString, Container);
}

Now what we want to achieve is to test if we can create a blob file to our local storage, read it and delete it.

[Fact]
public async Task AzureBlobStorageTest()
{
    // Arrange
    await _azureBlobStorage?.CreateTextFile("file.txt", Encoding.UTF8.GetBytes(Content))!;

    // Act
    var readTextFile = await _azureBlobStorage.ReadTextFile("file.txt");
    
    // Assert
    Assert.Equal(Content, readTextFile);

    // Finalizing
    await _azureBlobStorage.DeleteTextFile("file.txt");
}

Now let’s fire up our test, remember your azurite docker should be up and running.

Congrats, now you have just learned how to make a simple integration test of your Azure Blob Storage methods on a local environment without the need to have access to Azure Portal.

Download the project from GitHub.

Conclusion

In this article, we learned to interact with our C# code with Azure Blob Storage in the local environment. We created a simple integration test to test our Azure Blob Storage methods.

Now some of you would wonder and ask, this integration test works locally when my azurite docker is running, now how can I run this integration test on my GitHub action or Azure DevOps as part of CI (Continuous Integration) testing and still be able to fire up a docker image of Azurite?

This is what I will cover for GitHub action in the next and last article of this series.

Graphic credit
The banner in this article is designed by my ❤️ 15 years son Jassin Fahmi 😀.

6 thoughts on “How to make integration test for Azure Storage in C# – Part 2”

  1. Hi, please would you explain the code in your github repo ‘AzureBlobStorageIntegrationTests’? I feel that it is unit test. Confused.

    Reply
    • If you need to unit test the service, you can mock it as it is shown in this article https://itbackyard.com/how-to-make-mocked-unit-test-for-azure-storage/ but in our case here, we are doing an integration test of our system, of course, you can create storage as stage environment and make integration test against that stage. There is not one way of doing it, for instance, you can have local DEV, Test, UAT, and Production environment, where dev is mocked for local development, the test is for the ci/integration test, UAT is for the final test with real storage for QA testing, production environment with real storage for production. But again this is just an example, it is up to you how to test things.

      Reply

Leave a Reply to Maytham Fahmi Cancel reply