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:
dotnet --info output for .NET Core projects):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
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.