首页 > 解决方案 > 从另一个函数调用mongodb时如何模拟它?

问题描述

我在嘲笑 mongodb 时需要帮助。我正在使用mongomock来模拟 mongodb。

我的项目结构是:

-- my_mongo.py
-- code.py
-- my_test.py

my_mongo.py有:

from pymongo import MongoClient

 def get_db():
   client = MongoClient(os.environ['MONGODB_URI'])
   db = client['my_db']
   return db

 def insert(id, data):
     return get_db().results.insert_one(
          {
          "id": id,
          "data":df.to_json(),
          }).id

code.py

import my_mongo

def action():
    #do somethings
    my_mongo.insert(id, data)

my_test.py

import mongomock
import my_mongo
from unittest import mock


with patch.object(my_mongo.get_db().client, "client",  mongomock.MongoClient()):
    import code

def test_action_1():
    my_mongo.insert = mock.Mock(return_value=1)
    code.action()   

def test_action_2():
     with patch.object(my_mongo.get_db(), "get_db", mongomock.MongoClient().db):
     code.action()

它为两个测试抛出 pymongo.errors.ServerSelectionTimeoutError 。所以,它仍然进入 my_mongo.py 中的 insert_one() 方法。我希望在 test_action_1 my_mongo.insert 返回 1,但事实并非如此。

我错过了什么?

标签: pythonmongodbunit-testingmockingmongomock

解决方案


修补 mongodb 的那行代码是错误的。而不是使用patch.object(my_mongo.get_db(), "get_db", mongomock.MongoClient().db),你应该使用patch.object("my_mongo.get_db", return_value=mongomock.MongoClient()['my_db'])


以下是您的示例的完整可运行代码:

my_test.py

import mongomock
from unittest.mock import patch

import my_code
import my_mongo


def test_action_2():
    mocked_mongo = mongomock.MongoClient()
    with patch("my_mongo.get_db", return_value=mongomock.MongoClient()['my_db']):
        my_code.action()
        assert mocked_mongo.my_db.results.count_documents({'id': 'some_id'}) == 1

my_mongo.py

from pymongo import MongoClient

def get_db():
    client = MongoClient(os.environ['MONGODB_URI'])
    db = client['my_db']
    return db

def insert(id, data):
    return get_db().results.insert_one(
        {
            "id": id,
            "data": data,
        })

我的代码.py

import my_mongo

def action():
    #do somethings
    return my_mongo.insert('some_id', '{"a": 3}')

推荐阅读