如何为python单元测试模拟mongodb?

时间:2017-02-15 01:28:29

标签: python mongodb unit-testing mocking pymongo

我在Python 2.7中使用mock模块来模拟我的其他函数并使用

unittest用于编写单元测试。

我想知道模拟MongoDB是否与使用模拟功能不同(mock.patch正在调用的函数?)或者我是否需要为此目的使用另一个不同的包?

我认为我不希望运行测试mongodb实例。我想要的只是一些速度数据,并能够调用pymongo功能。我只是有点迷失,想到有没有办法为模块编写模拟(如pymongo),或mock模块可以实现的任何东西。

如果你能提供一个关于此的例子或教程,那就表示赞赏。

要测试的代码

from pymongo import MongoClient

monog_url = 'mongodb://localhost:27017'
client = MongoClient(monog_url)
db = client.db

class Dao(object):
   def __init__(self):
      pass

   def save(self, user):
      db_doc = {
        'name': user.name,
        'email': user.email
      }
      db.users.save(db_doc)

   def getbyname(self, user):
      db_doc = {
        'name': user.name,
      }
      return db.users.find(db_doc)

为了测试这个,我真的不想让测试mongodb运行起来!但是,我想我不想模拟db.userssave和db.users.find,因为我希望实际上能够检索我保存的数据并确保它在数据库中。我想我需要为我记忆中的每个模型创建一些灯具并使用它们。我需要一个外部工具才能这样做吗?

我正在考虑保留这样的假数据,只是不知道如何妥善处理它。

users = { 
    {'name' : 'Kelly', 'email' : 'kelly@gmail.com'},
    {'name': 'Sam', 'email': 'sam@gmail.com'}
}

5 个答案:

答案 0 :(得分:7)

我建议使用mongomock来模拟mongodb。它基本上是一个带有pymongo接口的内存中的mongodb,专门用于此目的。

https://github.com/mongomock/mongomock

答案 1 :(得分:1)

你当然可以模拟PyMongo,但我建议嘲笑MongoDB服务器本身。我已经为MongoDB编写了一个可以完全控制的纯Python模拟器,它可以响应MongoDB有线协议消息但是你选择:

http://mockupdb.readthedocs.io/tutorial.html

以下是将MockupDB与Python应用程序一起使用的示例:

https://emptysqua.re/blog/test-mongodb-failures-mockupdb/

它需要熟悉MongoDB有线协议,但无论如何这都是一项有用的技能。

答案 2 :(得分:1)

添加到@mirthbottle 答案,如果你想访问 mongo 对象的属性作为一个字段,你可以这样做,

class MongoDummybject:
    def __init__(self, _data):
        for _d in _data:
            setattr(self, _d, _data[_d])

return_data = {'name' : 'Nishant', 'email' : 'nishant@gmail.com'}

@mock.patch("pymongo.collection.Collection.find")
def test_name(self, mock_find):
    mock_find.return_value = MongoDummybject(return_data)

答案 3 :(得分:0)

如果您只是做一些简单的事情,并且您真的不需要按字段检索,也可以这样做。

@mock.patch("pymongo.collection.Collection.find")
def test_name(self, mock_find):
    mock_find.return_value = {'name' : 'Kelly', 'email' : 'kelly@gmail.com'}
    # rest of test

答案 4 :(得分:0)

对于包装在自定义异常中的单元测试异常,请在bulk_writeCollection之内修补功能(例如mongomock

@mock.patch("mongomock.collection.Collection.bulk_write", side_effect=BulkWriteError({}))
def test_bulk_wrt_err(self, blk_wrt_err):
    with self.assertRaises(SpecialBulkWriteExcep) as context:
        add_user()

示例代码here