Search code examples
.net.net-corenunitazure-storage

NSubstitute or moq ListBlobsSegmentedAsync and its ContinuationToken


I am trying to create the unit test case for the below method. I tried to mock the container, ListBlobsSegmentedAsync but the response.ContinuationToken is getting null. So code crashes in between. Can you guys suggest how to write the unit test for the below method.

public List<IListBlobItem> GetListBlobsAsync(CloudBlobContainer container)
        {
            BlobContinuationToken continuationToken = null;
            var results = new List<IListBlobItem>();

            do
            {
                var response = container.ListBlobsSegmentedAsync(continuationToken).Result;
                continuationToken = response.ContinuationToken;
                results.AddRange(response.Results);
            }
            while (continuationToken != null);
            return results;
        }

I have tried to write the unit test as below.

[TestMethod]
        public void GetListBlobsAsync_Test()
        {
            // Arrange
            var items = new List<IListBlobItem>();
            items.Add(new CloudBlockBlob(new Uri("http://bogus/myaccount/blob/myfiles/test1.txt")));
            items.Add(new CloudBlockBlob(new Uri("http://bogus/myaccount/blob/myfiles/test2.txt")));
            items.Add(new CloudBlockBlob(new Uri("http://bogus/myaccount/blob/myfiles/test3.txt")));
            var client = Substitute.For<CloudBlobClient>(new Uri("http://foo.bar/"), null);
            var continuationToken = new BlobContinuationToken() { NextMarker = "abc123" };


            var container = Substitute.For<CloudBlobContainer>(new Uri("http://foo.bar/"));
            client.GetContainerReference(Arg.Any<string>()).Returns(container);
            container.ListBlobsSegmentedAsync(Arg.Any<string>(), Arg.Any<bool>(),
                                                Arg.Any<BlobListingDetails>(),
                                                Arg.Any<int?>(),
                                                Arg.Any<BlobContinuationToken>(),
                                                Arg.Any<BlobRequestOptions>(),
                                                Arg.Any<OperationContext>(),
                                                Arg.Any<CancellationToken>())
                                                .Returns(ci => new BlobResultSegment(items.ToArray(), continuationToken));

            // Act
            var readDeleteOperations = new ReadDeleteOperations();
            var result = readDeleteOperations.GetListBlobsAsync(container);

            // Assert
            result.Count.Should().Be(items.Count);
        }

But ListBlobsSegmentedAsync method is not mocking properly and returning null. So please suggest how should i mock this method. Thanks in advance!!


Solution

  • It looks like the code is calling:

    ListBlobsSegmentedAsync(BlobContinuationToken)
    

    but the test is mocking:

    ListBlobsSegmentedAsync(String, Boolean, BlobListingDetails, Nullable<Int32>,
        BlobContinuationToken, BlobRequestOptions, OperationContext, CancellationToken)
    

    Try updating the test to stub out the same overload as the code, and please let me know if it still does not work as expected.