当前位置: 首页 > 知识库问答 >
问题:

如何单元测试MongoDB查询筛选器?

宦兴朝
2023-03-14

我有一个类似于下面的场景(为了清楚起见进行了简化):

public class ExampleRepository
{
    private readonly IMongoDatabase _db;

    public ExampleRepository(IMongoClient mongoClient)
    {
        this._db = mongoClient.GetDatabase("database");
    }

    public async Task<IEnumerable<Item>> GetItemsUsingFilter(Guid ownerId, DateTimeOffset createdSince, IEnumerable<ItemType> typesToIgnore)
    {
        var cursor = await this._db.GetCollection<Item>("Items")
            .FindAsync(item =>
                item.OwnerId == ownerId
                &&
                item.CreatedDate >= createdSince
                &&
                !typesToIgnore.Contains(item.Type)
            .SortByDescending(item => item.UserRating)
            .Limit(10);

        return await cursor.ToListAsync();
    }
}

我想编写单元测试来验证我的查询筛选器(以及排序和限制调用)的正确性,但我想不出如何设置测试数据来这样做。

我试过模拟IMongoDatabase并设置GetCollection调用以返回模拟IMongoCollection,但这不是正确的方法,因为我需要对真正的MongoCollection调用FindAsync调用。

我研究了通过拆分GetCollection调用然后使用标准LINQ应用过滤来更改存储库,但我不想从DB返回我的整个集合,然后在存储库层中查询它。

我发现了几个people单元测试MongoDB的示例,但这些示例都涉及到嘲弄FindAsync调用,这不是我需要做的。

我还考虑过在一个单独的类中将过滤器声明为表达式 >,这样我就可以单独测试它了,但我想在沿着这条路走之前探索其他选项,因为这会增加存储库层的复杂性。

共有1个答案

耿弘阔
2023-03-14

我没有使用过MongoDB,但下面是我从纯单元测试的角度出发的方法:

  • 注意到测试中方法有四个输入:IMongoClient依赖项(我认为它是间接输入)和三个参数(直接输入)。
  • 创建实现IMongoDatabase(MD)的对象,并模拟IMongoClient以返回该对象。
  • 创建一个实现IMongoCollection(MC)的对象,并由MD的GetCollection方法返回;MC实际上是您的测试数据。
  • 定义三个参数以传递给测试中的方法。

现在可以执行测试了。

看一下这个过度简化的示例(基于您的代码):

    public async Task<IEnumerable<string>> GetItemsUsingFilter()
    {
        var cursor = await this._db.GetCollection<string>("Items")
            .SortByDescending()
            .Limit(10);

        return await cursor.ToListAsync();
    }

如果GetCollection在生产环境中返回12个项目,“a”..“l”,我们希望返回“l”..“c”。此外,如果其他开发人员在SortByDescending之前错误地移动了Limit,我们希望测试失败(这将导致生产代码返回“j”..“a”)。

 类似资料:
  • 问题内容: 我有一个接受查询,通过SQL服务器运行它,检查错误并返回结果的类。如何对该课程进行单元测试? 编辑 :我将尝试更精确: 负责将查询传递到服务器。为了测试它是否确实这样做,抛出正确的异常等,我想将其连接到将要填充的模拟数据库。我的问题是- 怎么做?如何创建一个模拟“服务器”来处理呼叫? 问题答案: 只需传递一个SQL查询,然后将返回的结果与预期的结果进行比较即可。简单的。JUnit是一个

  • 我对meta_query有些情境问题。客户搜索四,但结果包括私人(原始词是私人的)。我想只显示IV(罗马数字)包括后。我的meta_query搜索从标题,子标题和自定义插件的描述。我找到了REGEXP,但我找不到从标题、子标题和描述中找到漫游数字的正确方法。 客户只能找到罗马数字,也可以找到任何单词等。

  • 问题内容: 我写了一堆查询来进行elasticsearch,我想为它们写一个单元测试。使用此后最小的量,可以进行弹性连接,从而可以进行一般的模拟。但是,当我尝试查看由查询生成的Json时,我没有设法以任何方式获取它。我试图按照这个帖子elsatic查询起订量,但它是只与旧版本的巢的,因为该方法并不再为对象。 我的测试如下: 还有其他方法可以实现我的要求吗? 问题答案: 最好的方法是使用捕获请求字节

  • 我看不到任何关于何时应该使用查询或过滤器或两者结合的描述。他们之间有什么区别?谁能解释一下吗?

  • 问题内容: 我正在寻找一种快速(真正快速)的方法来测试对hibernate查询的更改。我有一个庞大的应用程序,它具有成千上万个不同的HQL查询(在XML文件中)和100多个映射的类,我不想重新部署整个应用程序,以仅测试对查询的一个微小更改。 好的设置如何使我免于重新部署并启用快速查询检查? 问题答案: 在Intellij IDEA 8.1.3中,选择的机制称为“ Facet”。立即测试HQL查询:

  • 问题内容: 我选择的数据库是MongoDB。我正在编写一个数据层API,以从客户端应用程序中抽象实现细节- 也就是说,我实质上是在提供一个公共接口(一个充当IDL的对象)。 我正在以TDD方式测试自己的逻辑。在每个单元测试之前,调用一个方法来创建数据库单例,此后,当测试完成时,将调用一个方法来删除数据库。这有助于促进单元测试之间的独立性。 几乎所有单元测试(即 执行上下文查询 )都需要先进行某种插