模拟CloudStorageAccount和CloudTable for Azure表存储

Cok*_*oke 2 c# unit-testing mocking azure azure-table-storage

因此,我试图测试Azure表存储并模拟我依赖的东西。我的类的构造方式是,在构造函数中建立连接,即,创建一个新实例,CloudStorageAccount在其中创建StorageCredentials具有storageNameand 的实例storageKey。之后,创建一个实例CloudTable,在代码中进一步使用它来执行CRUD操作。我的课如下:

public class TableStorage : ITableStorage
    {
        private const string _records = "myTable";
        private CloudStorageAccount _storageAccount;
        private CloudTable _table;
        private ILogger<TableStorage> _logger;

        public AzureTableStorageService(ILogger<TableStorage> loggingService)
        {
            _storageAccount = new CloudStorageAccount(new StorageCredentials(
                 ConfigurationManager.azureTableStorageName, ConfigurationManager.azureTableStorageKey), true);
            _table = _storageAccount.CreateCloudTableClient().GetTableReference(_records);
            _table.CreateIfNotExistsAsync();
            _logger = loggingService;
        }

        //...
        //Other methods here
}
Run Code Online (Sandbox Code Playgroud)

_table在整个类中被重用于不同的目的。我的目标是模拟它,但是由于它是虚拟的并且没有实现任何接口,因此我无法提出一个简单的Mock解决方案,例如:

_storageAccount = new Mock<CloudStorageAccount>(new Mock<StorageCredentials>(("dummy", "dummy"), true));
_table  = new Mock<CloudTable>(_storageAccount.Object.CreateCloudTableClient().GetTableReference(_records));
Run Code Online (Sandbox Code Playgroud)

因此,当我尝试以这种方式构造单元测试时,我得到: Type to mock must be an interface or an abstract or non-sealed class.

我的目标是实现以下目标:

_table.Setup(x => x.DoSomething()).ReturnsAsync("My desired result");
Run Code Online (Sandbox Code Playgroud)

任何想法都受到高度赞赏!

小智 5

我还在努力实现对具有Azure表存储绑定的Azure功能的单元测试。我最终使用派生的CloudTable类工作,可以覆盖我使用的方法并返回固定的结果。

/// <summary>
/// Mock class for CloudTable object
/// </summary>
public class MockCloudTable : CloudTable
{

    public MockCloudTable(Uri tableAddress) : base(tableAddress)
    { }

    public MockCloudTable(StorageUri tableAddress, StorageCredentials credentials) : base(tableAddress, credentials)
    { }

    public MockCloudTable(Uri tableAbsoluteUri, StorageCredentials credentials) : base(tableAbsoluteUri, credentials)
    { }

    public async override Task<TableResult> ExecuteAsync(TableOperation operation)
    {
        return await Task.FromResult(new TableResult
        {
            Result = new ScreenSettingEntity() { Settings = "" },
            HttpStatusCode = 200
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我通过传递存储模拟器用于本地存储的配置字符串实例化了模拟类(请参阅https://docs.microsoft.com/zh-cn/azure/storage/common/storage-configure-connection-string)。

var mockTable = new MockCloudTable(new Uri("http://127.0.0.1:10002/devstoreaccount1/screenSettings"));
Run Code Online (Sandbox Code Playgroud)

在此示例中,“ screenSettings”是表的名称。

现在可以从单元测试将模拟类传递给Azure函数。

也许这就是您想要的?