C#: Unit Testing Azure Files SDK
Tags: azure, test, csharp, files
Published: 2022-06-10 01:31:11

Azure Files is great service to store files like local disk. I use C# SDK to access to the service, but unit testing was not straight forward.

# Sample code

Let's imagine we have C# code as below, which returns all share names from the Azure Files. I use DI for ShareServiceClient here. The code is quite simple, eh?

```csharp
using Azure.Storage.Files.Shares;
using Azure.Storage.Files.Shares.Models;

namespace AzureFilesSample;

public class AzureFileSampleService
{
    private readonly ShareServiceClient shareServiceClient;

    public AzureFileSampleService(ShareServiceClient shareServiceClient)
    {
        this.shareServiceClient = shareServiceClient;
    }
    public async Task<List<string>> GetFileSharesAsync()
    {
        List<string> fileShares = new List<string>();
        await foreach (ShareItem item in shareServiceClient
            .GetSharesAsync()
            .WithCancellation(CancellationToken.None))
        {
            fileShares.Add(item.Name);
        }

        return fileShares;
    }
}
```

# Unit test

To write unit test for the above code, we need to mock ShareServiceClient. However, I cannot instantiate ShareItem as it only has internal constructor. After I browse its source code in github, I found [ShareModelFactory](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/storage/Azure.Storage.Files.Shares/src/Models/ShareModelFactory.cs) class which let us instantiate related models.

This is the unit testing code. I use xUnit and moq library.

- Use ShareModelFactory to instantiate items
- Refer to [Azure Mocking](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/samples/Mocking.md) page to mock Azure response related object.

```csharp
[Fact]
public async Task Test1()
{
    Mock<ShareServiceClient> mockedShareServiceClient = new Mock<ShareServiceClient>();
    ShareItem shareItem1 = ShareModelFactory.ShareItem("name1", ShareModelFactory.ShareProperties());
    ShareItem shareItem2 = ShareModelFactory.ShareItem("name2", ShareModelFactory.ShareProperties());
    ShareItem[] pageValues = new[] { shareItem1, shareItem2 };
    Page<ShareItem> page = Page<ShareItem>.FromValues(pageValues, default, new Mock<Response>().Object);
    Pageable<ShareItem> pageable = Pageable<ShareItem>.FromPages(new[] { page });
    AsyncPageable<ShareItem> asyncPageable = AsyncPageable<ShareItem>.FromPages(new[] { page });
    mockedShareServiceClient.Setup(x => x.GetSharesAsync(ShareTraits.None, ShareStates.None, null, CancellationToken.None))
        .Returns(asyncPageable);

    AzureFileSampleService service = new AzureFileSampleService(mockedShareServiceClient.Object);

    var results = await service.GetFileSharesAsync();

    Assert.Equal("name1", results.First());
    Assert.Equal("name2", results.Last());
}
```

# Summary

Obviously, [Azure Mocking](https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/core/Azure.Core/samples/Mocking.md) is a great resource for unit test but we need to see source code to figure out how to write unit test time to time.

# Reference

[Async Enumerables](
https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8)