【问题标题】:How can I implement mock(s) for this unit test?如何为此单元测试实现模拟?
【发布时间】:2018-12-20 17:23:10
【问题描述】:

我需要为以下方法编写单元测试:

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;
}

我需要编写一个 xUnit 单元测试,它会在调用 blobRef.UploadTextAsync(fileContent) 时抛出一个 HttpException

Microsoft.WindowsAzure.Storage.CloudBlockBlob : Microsoft.WindowsAzure.Storage.Blob.ICloudBlob

但是CloudStorageAccount 没有实现接口,所以看起来我不能模拟它。

以下是一些示例单元测试代码,这些代码基于我对模拟的理解,并针对此特定场景拼凑而成:

var cloudBlockBlobMock = new Mock<ICloudBlob>();
cloudBlockBlobMock
    .Setup(cbb => cbb.UploadTextAsync("test"))
    .Throws<HttpException>();
var fileUploader = new FileUploader(cloudBlockBlobMock);
fileUploader.CreateFileAsync("test");

CreateFileAsync() 是可单元测试的吗?

在不模拟其父对象的情况下模拟子对象是否可能/有效?

【问题讨论】:

标签: c# azure unit-testing mocking moq


【解决方案1】:

微软在使库单元可测试时采用了另一种方法。这些类型没有实现接口,而是具有大多数虚拟方法。例如,CloudStorageAccount.CreateCloudBlobClient 方法是虚拟的。 You can mock those in Moq.

或者您可以使用将实现包装在接口中的包装器并使用它。参见例如Microsoft/Azure.Data.Wrapperspvredeveld/Azure.Storage.Wrappers。这些将提供一个您可以模拟的界面,但您必须更改现有代码库才能使用它们。

【讨论】:

【解决方案2】:

也许你可以使用下面的代码sn-p

Mock<CloudStorageAccount> obj = new Mock<CloudStorageAccount>();

然后你可以设置任何函数或属性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多