Azure-sdk-for-net: [QUERY] unit testing GetBlobLeaseClient().AcquireAsync

Created on 6 Jun 2020  路  7Comments  路  Source: Azure/azure-sdk-for-net

Query/Question
How are we expected to test BlobLeaseClient.AcquireAsync given that GetBlobLeaseClient is an extension method.


public async Task PerformActionAsync(BlobBaseClient client)
{
    var leaseClient = client.GetBlobLeaseClient();
    await leaseClient.AcquireAsync();
    try
    {
        await DoLeasedActionAsync();
    }
    finally
    {
        await leaseClient.ReleaseAsync();
    }
}

While it is possible to pass in a mock of BlobBaseClient the method GetBlobLeaseClient() is an extension method and cannot be mocked. it builds a concrete lease client:

        public static BlobLeaseClient GetBlobLeaseClient(
            this BlobContainerClient client,
            string leaseId = null) =>
            new BlobLeaseClient(client, leaseId);

attempting to call AcquireAsync on a BlobLeaseClient built from a mocked BlobBaseClient throws a null reference exception when it attempts to access the Pipeline member.

Environment:

  • Name and version of the Library package used: Azure.Storage.Blobs 12.4.2
  • Hosting platform or OS and .NET runtime version (dotnet --info output for .NET Core projects):
    .NET Core SDK (reflecting any global.json):
    Version: 3.1.202
    Commit: 6ea70c8dca

Runtime Environment:
OS Name: Windows
OS Version: 10.0.19551
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.202\

Host (useful for support):
Version: 3.1.4
Commit: 0c2e69caa6

  • IDE and version :Visual Studio 16.5.5
Client Service Attention Storage customer-reported needs-team-attention question

All 7 comments

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.

@seanmcc-msft Could you take a look at this? Looks like they're trying to make Mock Unit tests. This might be a feature request or bug. But at the same time there might not much we can do with changing what object we return for the GetBlobLeaseClient.

@amnguye, sure.

attempting to call AcquireAsync on a BlobLeaseClient built from a mocked BlobBaseClient throws a null reference exception when it attempts to access the Pipeline member.

I believe the solution would be to return a mock BlobLeaseClient from the mock BlobBaseClient, and setup the BlobLeaseClient.AcquireAsync() with the parameters you expect to be passed it.

@seanmcc-msft this is exactly my issue.
I'm attempting to return a mock BlobLeaseClient but I'm not sure how to do that without creating a BlobLeaseClientFactory and bypassing the call to GetBlobLeaseClient() altogether.

public async Task PerformActionAsync(BlobBaseClient client)
{
    var leaseClient = _leaseClientFactory.GetBlobLeaseClient(client);
    await leaseClient.AcquireAsync();
    try
    {
        await DoLeasedActionAsync();
    }
    finally
    {
        await leaseClient.ReleaseAsync();
    }
}

According to the SDK guideline found here the library should support mocking:
https://azure.github.io/azure-sdk/dotnet_introduction.html#dotnet-mocking

It seems that the method GetBlobLeaseClient() does not follow that guideline.

@henriblMSFT, I think you're right, it looks like it's not possible to mock and extension method.

I believe we chose to use extension methods to keep the BlobLeaseClient hidden from the Azure.Storage.Blobs namespace, with the concern being that it may confuse less-sophisticated users.

I think the best path forward is the workaround you suggested, creating a BlobLeaseClientFactory.

I'm going to close this issue, please re-open if you have any other questions.

Was this page helpful?
0 / 5 - 0 ratings