Reputation: 31
I am trying to mock mongodb's findasync,find methods in Xunit & .net core.
When i tried to mock the InsertOne,
mockcollection.setup(x=>x.InsertOneAsync(_newitem,null,It.IsAny<CancellationToken>()).Returns(task.CompletedTask);
but the find is throwing error "Extension Method FindAsync may not be used in setup/verify process.
mockcollection.setup(x=>x.FindAsync(It.IsAny<FilterDefinition<mytbl>>(),null,It.IsAny<CancellationToken>()).Returns(Task.FromResult(mockasyncursor.Object));
When i surfed all over the net all it says is extension methods cannot be mocked, the above method [FindAsync]
is a an extension method where as InsertOne
is not.
How can i mock the findasync
method?
Note: I tried using Mongo2go
to simulate the db and able to come up with positive results, but wanted to know how to do using mock ?
Method:
public async Task<IEnumerable<XX>> abc()
{
_logger.LogInformation("XXX");
var result = _context
.XX.FindAsync(_ => true, null, CancellationToken.None);
return ( await _context.XX.FindAsync(_ => true) ).ToList<XX>();
}
Unit Test Method:
public async Task XXX()
{
// Arrange
var XX = this.XX();
< IAsyncCursor < XX >> mockasynccursor = new Mock<IAsyncCursor<XX>>();
mockXXCollection = new Mock<IMongoCollection<XX>>();
mockasynccursor.Setup(_ => _.Current).Returns(ReadfromJson());
mockasynccursor.
SetupSequence
(_ => _.MoveNext(It.IsAny<CancellationToken>())).Returns(true).Returns(false);
//sample
var newitem = new XX { };
mockXXCollection.
Setup(x => x.InsertOneAsync(newitem, null, default(CancellationToken)))
.Returns(Task.CompletedTask);
//Error Here
mockXXCollection.Setup(x => x.FindAsync(It.IsAny<FilterDefinition<XX>>(), null, CancellationToken.None))
.Returns(Task.FromResult(mockasynccursor.Object));
//Message: System.NotSupportedException : Unsupported expression: x => x.FindAsync<XX>(It.IsAny<FilterDefinition<XX>>(), null, CancellationToken.None)
//Extension methods( here: IMongoCollectionExtensions.FindAsync) may not be used in setup / verification expressions.
mockStateFormContext.Setup(x => x.StateForms).Returns(mockXXCollection.Object);
// Act
var result = await xyzRepository.abc();
// Assert
}
Upvotes: 2
Views: 6100
Reputation: 247333
The instance FindAsync
definition looks like this
Task<IAsyncCursor<TProjection>> FindAsync<TProjection>(
FilterDefinition<TDocument> filter,
FindOptions<TDocument, TProjection> options = null,
CancellationToken cancellationToken = null
)
All the extension methods will eventually call back to this member.
When configuring the mock make sure that the instance member is explicitly being setup
//...
mockXXCollection
.Setup(_ => _.FindAsync(
It.IsAny<FilterDefinition<XX>>(),
It.IsAny<FindOptions<XX, XX>>(),
It.IsAny<CancellationToken>()
))
.ReturnsAsync(mockasynccursor.Object);
//...
Upvotes: 7