我在 mock 中挣扎IMongoCollection.Find
使用 Moq 进行单元测试的方法。
我尝试过的:
Mock<IMongoCollection<Person>> mockIMongoCollection = new Mock<IMongoCollection<Person>>();
mockIMongoCollection.SetupAllProperties();
mockIMongoCollection
.Setup(x => x.Find(
It.IsAny<FilterDefinition<Person>>(),
It.IsAny<FindOptions>()))
.Returns();
问题是我尝试使用 Returns()
返回的任何内容,它不起作用,我希望能够返回可转换为 List<Person>
的东西而且我无法模拟或创建 IFindFluent<Person,Person>
的实例正如 Find
的返回类型所建议的那样方法。
最佳答案
我知道这个问题有点老了,但是最近在开发模拟 mongo 驱动程序的单元测试时遇到了同样的问题,我没有找到模拟这个方法的具体方法。所以这是我的解决方案:
如前所述,它是一个不能被模拟的静态方法,您应该模拟内部将被调用的非静态方法。
Find 方法将创建并返回一个 FindFluent 实例,该实例实现了 IFindFluent 接口(interface)(以及扩展的 IAsyncCursorSource 接口(interface)),该接口(interface)将使用非静态收集方法,以及该接口(interface)的静态扩展方法。
所以你应该找到并分析找到后你将使用的方法,以及它使用的模拟组件。例如,将结果加载到列表中:
public List<Person> LoadPeople(IMongoCollection<Person> collection)
{
return collection.find(Builders<Person>.Filter.Empty).ToList();
}
测试它:
[Fact]
public void LoadPeopleTest()
{
var mockIMongoCollection = new Mock<IMongoCollection<Person>>();
var asyncCursor = new Mock<IAsyncCursor<Person>>();
var expectedResult = fixture.CreateMany<Person>(5);
mockIMongoCollection.Setup(_collection => _collection.FindSync(
Builders<Person>.Filter.Empty,
It.IsAny<FindOptions<Person>>(),
default))
.Returns(asyncCursor.Object);
asyncCursor.SetupSequence(_async => _async.MoveNext(default)).Returns(true).Returns(false);
asyncCursor.SetupGet(_async => _async.Current).Returns(expectedResult);
var result = LoadPeople(mockIMongoCollection.Object);
Assert.Equals(expectedResult, result);
}
涉及类:
https://github.com/mongodb/mongo-csharp-driver/blob/master/src/MongoDB.Driver/FindFluent.cs
关于c# - 如何使用 Moq 模拟 IMongoCollection.Find,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51417459/