最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Mocking Blobclient.DownloadToAsync(stream) using NSubstitute - Stack Overflow

programmeradmin0浏览0评论

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
  • Can you give some more context and/or code for what your tests are doing? Normally you wouldn't unit test the BlobClient itself. – Andrew B Commented Feb 7 at 22:01
  • Hi @AndrewB I added sample code that I want to unit test. I don't want to unit test the blobclient. I want to mock the DownloadTo method. So, I want to fill fileStream with a sample file. Wrappers should not be needed if I follow the docs of Microsoft. – LockTar Commented yesterday
  • Thanks for the extra details! I would still say that this isn't the right use of unit tests. They're for testing application logic; or put more simply, decisions/calculations. So for example, what calls GetMyDoc? 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 yesterday
  • Hi, I know how to write tests. I'm not testing dependencies. I'm testing if my dependency is correctly called and how my function GetMyDoc would react If I get an empty file, correct file etc. I also test if my blob path is correctly passed to GetBlobClient(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
  • But let's say, that the filestream is read and that I count the number of rows in the memorystream and I want to write 3 tests. How would it react with an empty file, a file with only headers and a file with 2 with rows and a header row. – LockTar Commented 3 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

You'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);
}
发布评论

评论列表(0)

  1. 暂无评论