Дразнить CloudBlockBlob и заставить его вернуть поток - PullRequest
3 голосов
/ 08 марта 2019

Я пытаюсь выполнить Moq для Azure CloudBlockBlob и заставить его вернуть поток, чтобы я мог проверить, правильно ли обрабатывает мой репозиторий BlobStorage вывод. Но почему-то возвращаемый поток всегда пуст.

Код юнит-теста:

        ....
        var stream = new MemoryStream();
        var writer = new StreamWriter(stream);
        writer.Write("sample data");
        writer.Flush();
        stream.Position = 0;

        var blobMock = new Mock<CloudBlockBlob>(new Uri("http://tempuri.org/blob"));
        blobMock
            .Setup(m => m.ExistsAsync())
            .ReturnsAsync(true);
        blobMock
            .Setup(m => m.DownloadToStreamAsync(It.IsAny<MemoryStream>()))
            .Returns(Task.FromResult(stream));
        ....

код хранилища:

        ....
        var blob = GetContainer(container).GetBlockBlobReference(name);
        if (await blob.ExistsAsync())
        {
            var ms = new MemoryStream();
            await blob.DownloadToStreamAsync(ms);
            ms.Seek(0, SeekOrigin.Begin);
            return ms;
        }
        ....

Таким образом, мой возвращенный поток ms всегда является пустым потоком, а не объектом stream, который я использую в своем методе Moq Returns(). Как я могу сделать, чтобы этот BLOB-файл возвратил мой поток пробы?

1 Ответ

2 голосов
/ 08 марта 2019

Это два разных потока.Возьмите поток, переданный в аргументе макета, в Callback и скопируйте тестовый поток поверх.

Например,

//....
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write("sample data");
writer.Flush();
stream.Position = 0;

var blobMock = new Mock<CloudBlockBlob>(new Uri("http://tempuri.org/blob"));
blobMock
    .Setup(m => m.ExistsAsync())
    .ReturnsAsync(true);
blobMock
    .Setup(m => m.DownloadToStreamAsync(It.IsAny<Stream>()))
    .Callback((Stream target) => stream.CopyTo(target)) //<---Something like this
    .Returns(Task.CompletedTask);
//....

На самом деле макет не возвращает поток.Предполагается, что он воздействует на поток, поэтому обратный вызов необходим для репликации ожидаемого поведения.

Обратите внимание

Копирование начинается с текущей позиции в текущем потоке,и не сбрасывает позицию целевого потока после завершения операции копирования.

Так что в этом случае вы можете сбросить его, если намерение было прочитать с цели

//...

.Callback((Stream target) => {
    stream.CopyTo(target);
    target.Position = 0;
})

//...
...