Пересмешка CloudStorageAccount и CloudTable для хранилища таблиц Azure - PullRequest
0 голосов
/ 28 ноября 2018

Поэтому я пытаюсь протестировать хранилище таблиц Azure и высмеивать вещи, от которых я зависю.Мой класс структурирован таким образом, что я устанавливаю соединение в конструкторе, то есть я создаю новый экземпляр CloudStorageAccount, в котором я создаю экземпляр StorageCredentials, который имеет storageName и 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
}

_table повторно используется в классе для разных целей.Моя цель состоит в том, чтобы издеваться над ним, но, поскольку он является виртуальным и не реализует никакого интерфейса, я не могу найти простое решение Mock, такое как:

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

Поэтому, когда я пытаюсьПостроить мой модульный тест таким образом, я получаю: Type to mock must be an interface or an abstract or non-sealed class.

Моя цель заключается в достижении чего-то вроде:

_table.Setup(x => x.DoSomething()).ReturnsAsync("My desired result");

Любые идеи высоко ценятся!

Ответы [ 2 ]

0 голосов
/ 24 июля 2019

Чтобы добавить ответ здесь, поскольку вы собираетесь использовать макетную среду, простая настройка объекта, который наследуется от CloudTable и предоставляет конструктор по умолчанию, должна позволить вам смоделировать сам унаследованный объект и контролировать то, что он возвращает:

public class CloudTableMock : CloudTable
{
    public CloudTableMock() : base(new Uri("http://127.0.0.1:10002/devstoreaccount1/screenSettings"))
    {
    }
}

Тогда это просто случай создания макета.Я использую NSubstitute, поэтому я сделал:

_mockTable = Substitute.For<CloudTableMock>();

, но я предполагаю, что Moq позволит:

_mockTableRef = new Mock<CloudTable>();
_mockTableRef.Setup(x => x.DoSomething()).ReturnsAsync("My desired result");
_mockTable = _mockTableRef.Object;

(Мой Moq немного ржавый, поэтому я угадываюприведенный выше синтаксис не совсем корректен)

0 голосов
/ 14 декабря 2018

Я также пытался реализовать модульный тест для функции 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
        });
    }
}

Я создал экземпляр класса mock, передав строку конфигурации, используемую для локального хранилища, эмулятором хранилища.(см. https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string).

var mockTable = new MockCloudTable(new Uri("http://127.0.0.1:10002/devstoreaccount1/screenSettings"));

В этом примере 'screenSettings' - это имя таблицы.

Класс mock теперь можно передать в функцию Azure из вашего устройстватест.

Может быть, это то, что вы ищете?

...