Unit Testing and Mocking MongoDB Extension Method in .NET Core – Part2

In Part 2 of the article, I shall talk about how to Unit Test and Mock MongoDB method .NET Core.

Today in this article, we will cover below aspects,

We shall use the Synchronous method using the extension method FindSync() to validate IAsyncCursor results.

We already looked at a Unit testing solution for an approach with filter criteria in the below article,





As discussed, Technically IAsyncCursor is equivalent to IEnumerable which provides the capability of iterating over the collection asynchronously.



A few extension methods are as below,



  • FindSync
  • FindAsync
  • InsertOneAsync



In this post, we shall write the unit test for the method that uses the FindSync method.



We shall be using the same naming conventions for unit testing that we learned in our last article,





Unit Test MongoDB Synchronous methods

As we are dealing with the target Synchronous method hence we will write a unit test and mock of synchronous extension methods.

Unit test and Mock IAsyncCursor

Let’s now mock IAsyncursor. Overall there are two methods that IAsyncursor exposes. We shall mock them easily.

The IAsyncCursor<TDocument> type exposes the following methods,

  • MoveNext()
  • MoveNextAsync()

As we are dealing with the Synchronous method we will mock MoveNext() method as below

            //Mock MoveNext
             
             Mock<IAsyncCursor<Book>> _bookCursor = new Mock<IAsyncCursor<Book>>();
            _bookCursor.Setup(_ => _.Current).Returns(_list); 
            _bookCursor
                .SetupSequence(_ => _.MoveNext(It.IsAny<CancellationToken>()))
                .Returns(true)
                .Returns(false);


The complete test method is as below,

        
        [Fact]
        public  void BookRepository_GetBookSync_Valid_Success()
        {
            //Arrange

            //Mock MoveNext

            Mock<IAsyncCursor<Book>> _bookCursor = new Mock<IAsyncCursor<Book>>();
            _bookCursor.Setup(_ => _.Current).Returns(_list);
            _bookCursor
                .SetupSequence(_ => _.MoveNext(It.IsAny<CancellationToken>()))
                .Returns(true)
                .Returns(false);

            //Mock FindSync

            _mockCollection.Setup(op => op.FindSync(It.IsAny<FilterDefinition<Book>>(),
            It.IsAny<FindOptions<Book, Book>>(),
            It.IsAny<CancellationToken>())).Returns(_bookCursor.Object);

            //Mock GetCollection

            _mockContext.Setup(c => c.GetCollection<Book>(typeof(Book).Name)).Returns(_mockCollection.Object);

            var bookRepo = new BookRepository(_mockContext.Object);

            //Act
            var result =  bookRepo.GetAllSync();

            //Assert 
            //Lets loop only first item and assert
            foreach (Book book in result)
            {
                Assert.NotNull(book);
                Assert.Equal(book.Name, _book.Name);
                Assert.Equal(book.Author, _book.Author);
                break;
            }

            //Verify if InsertOneAsync is called once 

            _mockCollection.Verify(c => c.FindSync(It.IsAny<FilterDefinition<Book>>(),
                It.IsAny<FindOptions<Book>>(),
                 It.IsAny<CancellationToken>()), Times.Once);
        }

Below is how I can set up the unit test with mockup data,

Unit Test and Mock MongoDB extension method .NET Core

Sometimes framework-dependent extension methods are really difficult to test.

In such scenarios, we should only test for its execution once or twice, etc. rather than actual results.

We can very much make use of the Assertion method like ‘Verify‘ to validate the same.

Unit Test MongoDB Asynchronous method

Please visit the below article for the Asynchronous method,

Other References :

Do you have any better suggestions to test the method with AsyncCursor?

Please sound off your comments below!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.