Getting started with testing for Azure Blob Storage : Mocking Azure Blob/File Storage SDK Using FakeItEasy
Hi Everyone!
As you are aware I have decided to move away from MOQ and insted we will use FakeItEasy for mocking the Azure Storage SDK. This post is adoptation of this which is using Moq.
You can find the full series of how to perform unit and integration tests for Azure Blob Storage using Azurite Test Containers, and xUnit.
Getting started with testing for Azure Blob Storage : Dependency Injection
Getting started with testing for Azure Blob Storage : Unit Test with help of Moq
Getting started with testing for Azure Blob Storage : Mocking Azure Blob/File Storage SDK
This Post - Getting started with testing for Azure Blob Storage : Mocking Azure Blob/File Storage SDK Using FakeItEasy (Alternative to MoQ)
We will use the same code base we used in the previous post. So, if you have not read the previous post, I would recommend to read it first before proceeding further as we will skip the code part and focus on the testing part.
Writing Unit Tests
Finally, we have reached to the point where we can write unit tests for AzBlobService
. Let’s write the unit tests for AzBlobService
using FakeItEasy and xUnit. For this, I have created seperate class named AzBlobServiceTest
which will contain all the unit tests for AzBlobService
in our unit test project.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class AzBlobServiceTest
{
private readonly StringWriter Output = new();
private const string _connectionName = "testconnection";
public AzBlobServiceTest()
{
Console.SetOut(Output);
}
[Fact]
public async Task File_Upload_Suceess()
{
// Arrange
var _azBlobServiceClientFactory = A.Fake<IAzureClientFactory<BlobServiceClient>>();
var _azBlobServiceClient = A.Fake<BlobServiceClient>();
var _azBlobContainerClient = A.Fake<BlobContainerClient>();
var _azBlobClient = A.Fake<BlobClient>();
var _azBlobSettingsOption = A.Fake<AzBlobSettingsOption>();
var blobContainerInfo = BlobsModelFactory.BlobContainerInfo(default, default);
var blobContentInfo = BlobsModelFactory.BlobContentInfo(default, default, default, default, default);
A.CallTo(() => _azBlobContainerClient.CreateIfNotExistsAsync(default, default, default, default)).Returns(Response.FromValue(blobContainerInfo, default!));
A.CallTo(() => _azBlobClient.UploadAsync(A.Dummy<Stream>(), default, default, default, default, default, default, default)).Returns(Response.FromValue(blobContentInfo, default!));
A.CallTo(() => _azBlobContainerClient.GetBlobClient(default)).Returns(_azBlobClient);
A.CallTo(() => _azBlobServiceClient.GetBlobContainerClient(default)).Returns(_azBlobContainerClient);
A.CallTo(() => _azBlobServiceClientFactory.CreateClient(default)).Returns(_azBlobServiceClient);
var _sut = new AzBlobService(_azBlobServiceClientFactory, _azBlobSettingsOption);
// Act
var result = await _sut.UploadFileToAzBlobAsync("samplefile.txt");
// Assert
Assert.True(result);
}
[Fact]
public async Task File_Upload_Fail()
{
// Arrange
var _azBlobServiceClientFactory = A.Fake<IAzureClientFactory<BlobServiceClient>>();
var _azBlobServiceClient = A.Fake<BlobServiceClient>();
var _azBlobContainerClient = A.Fake<BlobContainerClient>();
var _azBlobClient = A.Fake<BlobClient>();
var _azBlobSettingsOption = A.Fake<AzBlobSettingsOption>();
var blobContainerInfo = BlobsModelFactory.BlobContainerInfo(default, default);
var blobContentInfo = BlobsModelFactory.BlobContentInfo(default, default, default, default, default);
A.CallTo(() => _azBlobContainerClient.CreateIfNotExistsAsync(default, default, default, default)).Returns(Response.FromValue(blobContainerInfo, default!));
A.CallTo(() => _azBlobClient.UploadAsync(A.Dummy<Stream>(), default, default, default, default, default, default, default)).Returns(Response.FromValue(blobContentInfo, default!));
A.CallTo(() => _azBlobContainerClient.GetBlobClient(default)).Returns(_azBlobClient);
A.CallTo(() => _azBlobServiceClient.GetBlobContainerClient(default)).Returns(_azBlobContainerClient);
A.CallTo(() => _azBlobServiceClientFactory.CreateClient(default)).Returns(_azBlobServiceClient);
var _sut = new AzBlobService(_azBlobServiceClientFactory, _azBlobSettingsOption);
// Act
var result = await _sut.UploadFileToAzBlobAsync("");
// Assert
Assert.False(result);
Assert.Contains("Unable to upload blob. Reason", Output.ToString());
}
}
BlobServiceClient
and BlobContainerClient
and injecting it to AzBlobService
using AzBlobServiceClientFactory
. Also we tried to fake all the required methods of BlobServiceClient
and BlobContainerClient
which are used in AzBlobService
.
I have also created the scenario where file upload fails due to blank file name to show how to write negative unit tests.
Conclusion
In this article, we have learned how to write loosely coupled code for Azure Storage SDK and how to mock the Azure Storage SDK using FakeItEasy and xUnit. This whole series of articles was focused on Azure Blob Storage but you can use the same approach for Azure File Storage as well. For Azure File Storage, you just need to replace the BlobServiceClient
with FileServiceClient
and BlobContainerClient
with ShareClient
and BlobClient
with ShareFileClient
, and you are good to go. Also to mock the respose you will have FilesModelFactory
instead of BlobsModelFactory
.
You can find the source code here.