1

I got reference from this post and it seems they have a working solution on unit testing for DocumentDB Repository class.

[TestClass]
public class DocumentDBRepositoryShould {
    /// <summary>
    /// Fake IOrderedQueryable IDocumentQuery for mocking purposes
    /// </summary>        
    public interface IFakeDocumentQuery<T> : IDocumentQuery<T>, IOrderedQueryable<T> {

    }

    [TestMethod]
    public async Task ExecuteQueryAsync() {
        //Arrange
        var description = "BBB";
        var expected = new List<MyDocumentClass> {
            new MyDocumentClass{ Description = description },
            new MyDocumentClass{ Description = "ZZZ" },
            new MyDocumentClass{ Description = "AAA" },
            new MyDocumentClass{ Description = "CCC" },

        };
        var response = new FeedResponse<MyDocumentClass>(expected);

        var mockDocumentQuery = new Mock<IFakeDocumentQuery<MyDocumentClass>>();
        mockDocumentQuery
            .SetupSequence(_ => _.HasMoreResults)
            .Returns(true)
            .Returns(false);

        mockDocumentQuery
            .Setup(_ => _.ExecuteNextAsync<MyDocumentClass>(It.IsAny<CancellationToken>()))
            .ReturnsAsync(response);

        var client = new Mock<IDocumentClient>();

        client
            .Setup(_ => _.CreateDocumentQuery<MyDocumentClass>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
            .Returns(mockDocumentQuery.Object);

        var cosmosDatabase = string.Empty;

        var documentsRepository = new DocumentDBRepository<MyDocumentClass>(cosmosDatabase, client.Object);

        //Act
        var query = documentsRepository.GetQueryable(); //Simple query.

        var actual = await documentsRepository.ExecuteQueryAsync(query);

        //Assert
        actual.Should().BeEquivalentTo(expected);
    }
}

Basically the code is to compare the query result and the expected result. But I don't understand where do they get the query result? and where is the "fake" database that they query from? For example, for this line of code:

var actual = await documentsRepository.ExecuteQueryAsync(query);

Which database is it calling?

superninja
  • 3,114
  • 7
  • 30
  • 63

1 Answers1

3

This unit test is using Moq to create a mock object of a IFakeDocumentQuery which is a interface implementing IDocumentQuery.

The user who wrote this doesn't care how the document client will return the expected data. That's why in these lines

mockDocumentQuery
        .SetupSequence(_ => _.HasMoreResults)
        .Returns(true)
        .Returns(false);

mockDocumentQuery
        .Setup(_ => _.ExecuteNextAsync<MyDocumentClass>(It.IsAny<CancellationToken>()))
        .ReturnsAsync(response);

he/she/they sets up the mocked document query to return a specific response when the ExecuteNextAsync method is called with any CancellationToken and in these lines

client
        .Setup(_ => _.CreateDocumentQuery<MyDocumentClass>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
        .Returns(mockDocumentQuery.Object);

he/she/they is setting up the document query created to return the mocked document query object.

The idea is that a unit test should have nothing to do with any external call, that's why we are mocking the response when there is an external call.

Nick Chapsas
  • 6,872
  • 1
  • 20
  • 29