使用模拟 MongoDB 服务器进行单元测试

Posted

技术标签:

【中文标题】使用模拟 MongoDB 服务器进行单元测试【英文标题】:Use mock MongoDB server for unit test 【发布时间】:2013-04-01 15:44:26 【问题描述】:

我必须使用 MongoDB 存储实现 Python 代码的鼻子测试。是否有任何允许我初始化模拟内存 MongoDB 服务器的 python 库?

我正在使用持续集成。所以,我希望我的测试独立于任何运行 MongoDB 的服务器。 有没有办法在内存中模拟 mongoDM 服务器以独立于连接到 Mongo 服务器来测试代码?

提前致谢!

【问题讨论】:

【参考方案1】:

我也在使用 pymongo 并且 MockupDB 非常适合我的目的(集成测试)。

使用起来很简单:

from mockupdb import *
server = MockupDB()
port = server.run()
from pymongo import MongoClient
client = MongoClient(server.uri)
import module_i_want_to_patch
module_i_want_to_patch.client = client

可以查看MockupDB官方教程here

【讨论】:

【参考方案2】:

您可以使用Ming,它具有内存中的 mongo db pymongo 连接替换。

import ming
mg = ming.create_datastore('mim://')
mg.conn # is the connection
mg.db # is a db with no name
mg.conn.somedb.somecol
# >> mim.Collection(mim.Database(somedb), somecol)
col = mg.conn.somedb.somecol
col.insert('a': 1)
# >> ObjectId('5216ac3fe0323a1218f4e9aa')
col.find().count()
# >> 1

【讨论】:

同上。我尝试使用 MongoDB => 3.0 进行 ming,但大多数时候都失败了,因为 ming 不是为此而生的。只要复杂性增加,它就会越来越不可靠。 @HéctorValverdePareja 你想做什么失败了?从 sn-p 中可以看出,插入和查找工作正常。 对不起,当我说“以上”时,我的意思是我在批准的答案中添加的评论。这是关于兼容性。 Ming 不支持最新版本的 pymongo(后来到 3.0),例如 Ming 不支持函数“insert_one()”而不是“insert()”(或者在我玩的 2-3 个月前不支持)它。【参考方案3】:

你可以试试:https://github.com/vmalloc/mongomock,它旨在成为一个小型库,用于模拟 pymongo 集合对象以进行测试。

但是,与确保某些模拟库的功能完整相比,我不确定仅运行 mongodb 的成本是否过高。

【讨论】:

如果能有一个例子来说明 mongoengine 和 mongomock 如何很好地协同工作,那就太好了。 确保您与 3.0 之后的版本具有良好的兼容性。在升级服务器和驱动程序 (pymongo) 后,我立即尝试使用所有框架来模拟我的收藏集失败 @badgley 只需两行代码:import mongomock client = mongomock.MongoClient() 就可以了。之后,您可以像使用 pymongo 一样使用 client.my_db.my_coll.insert_one('a': 1)【参考方案4】:

我不了解 Python,但我对 C# 也有类似的担忧。我决定在我的工作站上运行一个真实的 Mongo 实例,指向一个空目录。这不是很好,因为代码不是孤立的,但它又快又容易。

在测试过程中只有数据访问层真正调用了 Mongo。其余的可以依赖于数据访问层的模拟。当我真的想验证与 Mongo 的交互是否正确时,我觉得伪装 Mongo 不值得。

【讨论】:

+1 我不明白孤立地测试一切的愿望。您可以期望的最好的结果是它的行为就像真实的东西。只测试真实的东西。配置专用测试数据库。 这是一个正确的观点,但单独测试的一个原因是您可以更轻松地将其提供给其他人,以便他们也可以在他们的环境中进行测试。如果他们也必须建立一个外部流程,这将变得更加繁重(尽管在这种情况下可能值得)。 此外,如果测试要在管道中运行,您无法确定是否安装了数据库。

以上是关于使用模拟 MongoDB 服务器进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

模拟 Websocket 服务器进行单元测试

使用 Moq 模拟单元测试的异步方法

在 Grails 中对服务进行单元测试时如何模拟请求

如何模拟 acegi 身份验证服务以进行单元测试?

如何在服务层单元测试中模拟数据库结果?

如何在 Angular 组件中模拟服务功能以进行单元测试