Reputation: 171
I need to write a unit test for the following method:
private async Task<bool> CreateFileAsync(string fileContent, string containerName, string fileName, string connectionString)
{
CloudStorageAccount cloudStorageAccount = await GetCloudStorageAccount(connectionString);
CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
CloudBlobContainer containerRef = blobClient.GetContainerReference(containerName);
CloudBlockBlob blobRef = containerRef.GetBlockBlobReference(fileName);
await blobRef.UploadTextAsync(fileContent);
return true;
}
I need to write an xUnit unit test which will throw an HttpException
when blobRef.UploadTextAsync(fileContent)
is called.
Microsoft.WindowsAzure.Storage.CloudBlockBlob : Microsoft.WindowsAzure.Storage.Blob.ICloudBlob
But CloudStorageAccount
doesn't implement an interface so it does not appear that I can mock it.
Here's some sample unit test code based on what I understand about mocking and pieced together for this particular scenario:
var cloudBlockBlobMock = new Mock<ICloudBlob>();
cloudBlockBlobMock
.Setup(cbb => cbb.UploadTextAsync("test"))
.Throws<HttpException>();
var fileUploader = new FileUploader(cloudBlockBlobMock);
fileUploader.CreateFileAsync("test");
Is CreateFileAsync()
unit-testable?
Is it possible/valid to mock a child object without mocking its parent object?
Upvotes: 1
Views: 6414
Reputation: 315
Maybe you can use the below code snippet
Mock<CloudStorageAccount> obj = new Mock<CloudStorageAccount>();
and then you can setup any function or property
Upvotes: 0
Reputation: 29720
Microsoft took another approach when it came to making the libs unit testable. Instead of implementing interfaces, the types have most methods virtual. For example, the CloudStorageAccount.CreateCloudBlobClient
method is virtual. You can mock those in Moq.
Or you could use a wrapper that wraps the implementation in an interface and use that. See e.g. Microsoft/Azure.Data.Wrappers or pvredeveld/Azure.Storage.Wrappers. These will provide an interface you can mock but you have to change your existing codebase to use them.
Upvotes: 5