c# - 如何使用 Moq 模拟 IMongoCollection.Find

标签 c# mongodb unit-testing .net-core moq

我在 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/IMongoCollectionExtensions.cs

https://github.com/mongodb/mongo-csharp-driver/blob/master/src/MongoDB.Driver/FindFluent.cs

https://github.com/mongodb/mongo-csharp-driver/blob/master/src/MongoDB.Driver.Core/IAsyncCursorSource.cs

关于c# - 如何使用 Moq 模拟 IMongoCollection.Find,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51417459/

相关文章:

c# - 如何从另一个矩形中减去一个矩形?

c# - 在 c# 中替代 php 的 explode/implode-functions

c# - 根据多个条件外部连接两个数据表

unit-testing - Grails中的单元测试Promise任务

使用 NSTimer 通过单元测试后,iOS 逻辑单元测试目标崩溃

javascript - ASP.net - 将列表从代码隐藏传递到 java 脚本的最佳方法是什么?

javascript - MongoDB/Meteor/Export MONGO_URL 到部署的应用程序

mongodb - 查找查询结果到List

mongodb - 从MongoDB中的数组中删除元素

java - 如何模拟 JestClient、elasticSearch