Jon
Jon

Reputation: 40062

Mock BlobClient for Azure Function

I have an Azure Function that has a blob trigger, in my function method args I expose the Blob itself via BlobClient and the name of the file uploaded.

[FunctionName("MyFunc")]
public async Task RunAsync([BlobTrigger("upload/{name}", Connection = "DataLake")]
                            BlobClient blob, string name)
{
    var propertiesResponse = await blob.GetPropertiesAsync();
    var properties = propertiesResponse.Value;
    var metadata = properties.Metadata;

    //do stuff with metadata
                
    if (metadata.TryGetValue("activityId", out var activityId))
    {

    }

    using (var stream = await blob.OpenReadAsync())
    using (var sr = new StreamReader(stream))
    {
        //do some stuff with blob
    }
}

I would like to unit test this function and was trying to mock BlobClient but having issues using the Moq library. I have found BlobsModelFactory that aims to help mocking but I can't see anything for BlobClient. Has anyone managed to mock BlobClient?

Upvotes: 6

Views: 13690

Answers (1)

Peter Bons
Peter Bons

Reputation: 29840

In line with the new Azure SDK guidelines public methods are marked virtual so they can be mocked:

A service client is the main entry point for developers in an Azure SDK library. Because a client type implements most of the “live” logic that communicates with an Azure service, it’s important to be able to create an instance of a client that behaves as expected without making any network calls.

  1. Each of the Azure SDK clients follows mocking guidelines that allow their behavior to be overridden:
  2. Each client offers at least one protected constructor to allow inheritance for testing. All public client members are virtual to allow overriding.

In case of the BlobClient mocking can be done like this*:

var mock = new Mock<BlobClient>();
    var responseMock = new Mock<Response>();
    mock
        .Setup(m => m.GetPropertiesAsync(null, CancellationToken.None).Result)
        .Returns(Response.FromValue<BlobProperties>(new BlobProperties(), responseMock.Object))

A lot of stuff, like BlobProperties, can be mocked using the static class BlobsModelFactory, some examples:

var blobProps = BlobsModelFactory.BlobProperties(blobType: BlobType.Block);
var result = BlobsModelFactory.BlobDownloadResult(content: null);

Additional references:

*Code is for demonstration only, the references give clues on how to use BlobsModelFactory

Upvotes: 8

Related Questions