I'm trying to Moq an Azure CloudBlockBlob
and have it return a Stream
so that I can test whether my BlobStorage
repository is handling the output correctly.
But somehow the returned stream is always empty.
Unit test code:
//....
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));
//....
Repository code:
//....
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;
}
//....
So my returned MemoryStream ms
is always an empty stream and not the stream
object I'm using in my Moq Returns()
method.
How can I have that blob return my sample stream?
Those are two different streams. Grab the stream passed in the argument of the mock in a Callback
and copy the test stream over.
For example
//....
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);
//....
The mock does not actually return a stream. It is suppose to act on the stream, which is why the callback is needed to replicated the expected behavior.
Take note
Copying begins at the current position in the current stream, and does not reset the position of the destination stream after the copy operation is complete.
So in that case you might want to reset it if the intention was to read from the target
//...
.Callback((Stream target) => {
stream.CopyTo(target);
target.Position = 0;
})
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With