IBinder 的模拟在单元测试时失败 Activity 功能
Mock of IBinder fails when unit testing Activity Function
我正在尝试测试具有以下定义的 activity 函数:
[FunctionName(nameof(LoadReferenceFromBlobStorage))]
public static async Task<string> Run([ActivityTrigger] string blobName,
IBinder binder,
ILogger log)
{
StorageAccountAttribute storageAccountAtt = new StorageAccountAttribute("AzureWebJobsStorage");
CloudStorageAccount storageAccount = await binder.BindAsync<CloudStorageAccount>(storageAccountAtt, CancellationToken.None);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
//...
}
我在单元测试中将 IBinder
模拟为:
[TestMethod]
public async Task GetReference()
{
var attribute = new StorageAccountAttribute("UseDevelopmentStorage=true;");
var mock = new Mock<IBinder>();
CloudStorageAccount mockedResult = null;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true;", out mockedResult);
mock.Setup(x => x.BindAsync<CloudStorageAccount>(attribute, CancellationToken.None))
.ReturnsAsync(mockedResult);
ILogger logger = NullLoggerFactory.Instance.CreateLogger("log");
var res = await LoadReferenceFromBlobStorage.Run("name", mock.Object, logger);
//...
}
测试调用 activity 成功但 binder.BindAsync
的结果总是 null.
我是不是漏掉了什么?
您正在比较设置中的两个单独实例和测试中实际调用的实例。
被测方法正在使用硬编码 "AzureWebJobsStorage"
创建自己的 StorageAccountAttribute
实例,而测试正在使用另一个实例作为设置表达式。这些在进行测试时将不匹配,因此模拟将 return null 作为经验。
尝试使用It.IsAny<T>()
是期望表达式来放松设置。
//Arrange
CloudStorageAccount mockedResult = null;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true;", out mockedResult);
var mock = new Mock<IBinder>();
mock
.Setup(x => x.BindAsync<CloudStorageAccount>(It.IsAny<StorageAccountAttribute>(), CancellationToken.None))
.ReturnsAsync(mockedResult);
ILogger logger = Mock.Of<ILogger>();
//Act
var res = await LoadReferenceFromBlobStorage.Run("name", mock.Object, logger);
//Assert
//...
这将允许
CloudStorageAccount storageAccount = await binder.BindAsync<CloudStorageAccount>(storageAccountAtt, CancellationToken.None);
在调用时按预期运行。
关于 StorageAccountAttribute
硬编码参数,您可能还需要考虑重构它,以便在测试时可以替换它,以免测试时使用的存储出现问题。
我正在尝试测试具有以下定义的 activity 函数:
[FunctionName(nameof(LoadReferenceFromBlobStorage))]
public static async Task<string> Run([ActivityTrigger] string blobName,
IBinder binder,
ILogger log)
{
StorageAccountAttribute storageAccountAtt = new StorageAccountAttribute("AzureWebJobsStorage");
CloudStorageAccount storageAccount = await binder.BindAsync<CloudStorageAccount>(storageAccountAtt, CancellationToken.None);
CloudBlobClient client = storageAccount.CreateCloudBlobClient();
//...
}
我在单元测试中将 IBinder
模拟为:
[TestMethod]
public async Task GetReference()
{
var attribute = new StorageAccountAttribute("UseDevelopmentStorage=true;");
var mock = new Mock<IBinder>();
CloudStorageAccount mockedResult = null;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true;", out mockedResult);
mock.Setup(x => x.BindAsync<CloudStorageAccount>(attribute, CancellationToken.None))
.ReturnsAsync(mockedResult);
ILogger logger = NullLoggerFactory.Instance.CreateLogger("log");
var res = await LoadReferenceFromBlobStorage.Run("name", mock.Object, logger);
//...
}
测试调用 activity 成功但 binder.BindAsync
的结果总是 null.
我是不是漏掉了什么?
您正在比较设置中的两个单独实例和测试中实际调用的实例。
被测方法正在使用硬编码 "AzureWebJobsStorage"
创建自己的 StorageAccountAttribute
实例,而测试正在使用另一个实例作为设置表达式。这些在进行测试时将不匹配,因此模拟将 return null 作为经验。
尝试使用It.IsAny<T>()
是期望表达式来放松设置。
//Arrange
CloudStorageAccount mockedResult = null;
CloudStorageAccount.TryParse("UseDevelopmentStorage=true;", out mockedResult);
var mock = new Mock<IBinder>();
mock
.Setup(x => x.BindAsync<CloudStorageAccount>(It.IsAny<StorageAccountAttribute>(), CancellationToken.None))
.ReturnsAsync(mockedResult);
ILogger logger = Mock.Of<ILogger>();
//Act
var res = await LoadReferenceFromBlobStorage.Run("name", mock.Object, logger);
//Assert
//...
这将允许
CloudStorageAccount storageAccount = await binder.BindAsync<CloudStorageAccount>(storageAccountAtt, CancellationToken.None);
在调用时按预期运行。
关于 StorageAccountAttribute
硬编码参数,您可能还需要考虑重构它,以便在测试时可以替换它,以免测试时使用的存储出现问题。