I saw a different issue answer that is related but I can't get my method mocked.
I'm using the blobClient.DownloadToAsync(fileStream)
method. I want to create multiple tests. A test for a download with an empty file, a file with only CSV headers and a file with CSV headers and a line.
I tried everything but my stream is empty when I run the test. Any suggestions?
Code that I'm using for a test with headers:
// Create a memory stream to simulate the downloaded content
var memoryStream = new MemoryStream();
var writer = new StreamWriter(memoryStream);
writer.WriteLine("Header1,Header2,Header3");
writer.Flush();
//memoryStream.Position = 0;
var t = BlobsModelFactory.BlobDownloadStreamingResult(memoryStream);
var val = Response.FromValue(t, Substitute.For<Response>());
var returnVal = val.GetRawResponse();
blobClient.DownloadToAsync(Arg.Any<Stream>()).Returns(returnVal);
I think that I used the correct BlobsModelFactory method. I debugged the code of Microsoft and searched for a similar model in the factory.
The code that I want to test is something like this. The clients are injected into my class.
public async Task<int> GetMyDoc(MyCommand command)
{
var blobPath = command.blobPath;
// Get container client
var blobContainerClient = _blobServiceClient.GetBlobContainerClient(command.containerId);
// Get the blob client for the blob path.
var blobClient = blobContainerClient.GetBlobClient(blobPath);
using var fileStream = new MemoryStream();
await blobClient.DownloadToAsync(fileStream);
using var sr = new StreamReader(fileStream);
fileStream.Position = 0;
var rowNumber = 0;
while (!sr.EndOfStream)
{
// Other logic will be done here but for simplicity just count the number of rows...
rowNumber++;
}
return rowNumber;
}
I saw a different issue answer that is related but I can't get my method mocked.
I'm using the blobClient.DownloadToAsync(fileStream)
method. I want to create multiple tests. A test for a download with an empty file, a file with only CSV headers and a file with CSV headers and a line.
I tried everything but my stream is empty when I run the test. Any suggestions?
Code that I'm using for a test with headers:
// Create a memory stream to simulate the downloaded content
var memoryStream = new MemoryStream();
var writer = new StreamWriter(memoryStream);
writer.WriteLine("Header1,Header2,Header3");
writer.Flush();
//memoryStream.Position = 0;
var t = BlobsModelFactory.BlobDownloadStreamingResult(memoryStream);
var val = Response.FromValue(t, Substitute.For<Response>());
var returnVal = val.GetRawResponse();
blobClient.DownloadToAsync(Arg.Any<Stream>()).Returns(returnVal);
I think that I used the correct BlobsModelFactory method. I debugged the code of Microsoft and searched for a similar model in the factory.
The code that I want to test is something like this. The clients are injected into my class.
public async Task<int> GetMyDoc(MyCommand command)
{
var blobPath = command.blobPath;
// Get container client
var blobContainerClient = _blobServiceClient.GetBlobContainerClient(command.containerId);
// Get the blob client for the blob path.
var blobClient = blobContainerClient.GetBlobClient(blobPath);
using var fileStream = new MemoryStream();
await blobClient.DownloadToAsync(fileStream);
using var sr = new StreamReader(fileStream);
fileStream.Position = 0;
var rowNumber = 0;
while (!sr.EndOfStream)
{
// Other logic will be done here but for simplicity just count the number of rows...
rowNumber++;
}
return rowNumber;
}
Share
Improve this question
edited 3 hours ago
LockTar
asked Feb 7 at 19:33
LockTarLockTar
5,4653 gold badges48 silver badges75 bronze badges
5
|
1 Answer
Reset to default 0You're mocking the Response
but instead of using the Stream
of the Response
you're expecting the data to be copied to the Stream
you supplied in the arguments. Once you notice that it's quite easy to mock the behavior:
blobClientSub
.DownloadToAsync(Arg.Do<Stream>(memoryStream.CopyTo))
.Returns(responseSub);
edit
The full test case:
[Fact]
public async Task Document_contains_one_row()
{
// Arrange
var blobServiceClient = Substitute.For<BlobServiceClient>();
var blobContainerClient = Substitute.For<BlobContainerClient>();
var blobClient = Substitute.For<BlobClient>();
var response = Substitute.For<Response>();
blobServiceClient
.GetBlobContainerClient(Arg.Any<string>())
.Returns(blobContainerClient);
blobContainerClient
.GetBlobClient(Arg.Any<string>())
.Returns(blobClient);
using var memoryStream = new MemoryStream();
using (var writer = new StreamWriter(memoryStream, leaveOpen: true))
{
writer.WriteLine("Header1,Header2,Header3");
}
memoryStream.Position = 0;
blobClient
.DownloadToAsync(Arg.Do<Stream>(memoryStream.CopyTo))
.Returns(response);
// Act
var myService = new MyService(blobServiceClient);
var rowCount = await myService.GetMyDoc(new MyCommand
{
containerId = "containerId",
blobPath = "blobPath"
});
// Assert
Assert.Equal(1, rowCount);
}
DownloadTo
method. So, I want to fillfileStream
with a sample file. Wrappers should not be needed if I follow the docs of Microsoft. – LockTar Commented yesterdayGetMyDoc
? That might be something to unit test. Currently, you're trying to unit test some code that doesn't have any logic in it. You're trying to test dependencies rather than logic. Hope that helps a bit. Happy to explain more if you'd like? – Andrew B Commented yesterdayGetMyDoc
would react If I get an empty file, correct file etc. I also test if my blob path is correctly passed toGetBlobClient(blobPath)
. The path is created with multiple values. But that all is not my question. And I removed all other business logic so I get a clean question here on StackOverflow. – LockTar Commented 3 hours ago