MongoDB Mock and Unit Test a method returning IAsyncCursor
In this article, I shall talk about how to perform MongoDB Mock and Unit Test a method returning IAsyncCursor Synchronously
Today in this article, we will cover below aspects,
We shall use the below example and write a test method with mocking.
Below examples are already discussed in detail in our post-MongoDB Repository implementation in .NET Core with example
Example
Below is an example method for which we shall be writing mocking and unit test cases.
public IEnumerable<TEntity> GetAllSync()
{
var all = _dbCollection.Find(Builders<TEntity>.Filter.Empty,null);
return all.ToList();
}
Let’s define the constructor for initial setup up (If using XUnit this constructor shall execute for every test case and set up initial test data required for each test case)
Constructor for the Test class
Please see here below article for constructor initialization,
IAsyncCursor and Mocking
Let’s now mock IAsyncursor. Overall there are two methods that IAsyncursor exposes.
The IAsyncCursor<TDocument> type exposes the following methods,
- MoveNext()
- MoveNextAsync()
For Asynchronous method mocking, please visit here – MongoDB Mock and Unit Test a method returning IAsyncCursor
We shall mock MoveNext() for synchronous operation,
//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);
We shall set up current as a list of books as defined in the mock above.
Define Test Methods as below,
[Fact]
public void BookRepository_GetBookSync_Valid_Success()
{
//Arrange
//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
//loop only first item and assert all details
foreach (Book book in result)
{
Assert.NotNull(book);
Assert.Equal(book.Name, _book.Name);
Assert.Equal(book.Author, _book.Author);
break;
}
//Verify if FindSync is called once
_mockCollection.Verify(c =>
c.FindSync(It.IsAny<FilterDefinition<Book>>(),
It.IsAny<FindOptions<Book>>(),
It.IsAny<CancellationToken>()), Times.Once);
}
With the above code and mock setup, I can very much unit test actual result vs expected result easily.
Apart from that, I can very much Assert using Verify() to confirm if the extension method has been invoked once.
Other references :
Do you have any better suggestions to test the method with AsyncCursor?
Please sound off your comments below!
Happy Coding !!
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.