如何在pytest单元测试中实现mongomock Mock数据库跨用例持久化?
解决mongomock跨pytest测试用例持久化Mock数据库的问题
你当前的问题是每个测试用例通过mongomock.patch装饰器独立创建Mock环境,导致数据无法跨测试复用。以下两种方案可以实现Mock数据库的跨用例持久化:
方案一:使用pytest Fixture(推荐)
利用pytest的fixture作用域(scope)控制Mock客户端的生命周期,让它在整个模块或测试会话中只初始化一次,所有测试用例共享同一套Mock数据。
步骤1:定义全局Fixture
在测试文件或conftest.py中定义fixture:
import mongomock import pytest @pytest.fixture(scope="module") # scope可选值:module(同模块测试共享)/session(所有测试共享) def shared_mongo_client(): # 创建全局Mock客户端并初始化数据 client = mongomock.MongoClient("server.com") init_docs = [{"Name": "John"}, {"Name": "Jack"}] client.db.collection.insert_many(init_docs) return client
步骤2:在测试用例中复用Fixture
无需再使用mongomock.patch装饰器,直接注入fixture即可:
def test_func1(shared_mongo_client): # 直接使用已初始化的集合 doc = shared_mongo_client.db.collection.find_one({"Name": "John"}) assert doc["Name"] == "John" # 其他业务断言 def test_func2(shared_mongo_client): doc_count = shared_mongo_client.db.collection.count_documents({}) assert doc_count == 2 # 其他业务断言
方案二:复用全局Mock服务器
如果你的代码依赖pymongo.MongoClient的实际调用(必须用mongomock.patch拦截),可以创建全局Mock服务器并在每个patch中复用:
import mongomock import pymongo # 初始化全局Mock服务器及数据 global_mock_server = mongomock.MongoClient().server init_client = mongomock.MongoClient(server=global_mock_server) init_docs = [{"Name": "John"}, {"Name": "Jack"}] init_client.db.collection.insert_many(init_docs) # 在测试用例中复用全局服务器 @mongomock.patch(servers=(('server.com', 27017),), server=global_mock_server) def test_func1(): client = pymongo.MongoClient("server.com") assert client.db.collection.count_documents({}) == 2 @mongomock.patch(servers=(('server.com', 27017),), server=global_mock_server) def test_func2(): client = pymongo.MongoClient("server.com") assert client.db.collection.find_one({"Name": "Jack"}) is not None
注意事项
- 如果测试用例会修改Mock数据(如插入/删除/更新),会影响其他测试用例的结果。若需要测试隔离,建议保持每个测试独立初始化数据,不要使用持久化方案。
- 选择fixture的
scope时,module适合同文件内的测试共享,session适合整个测试项目共享。
内容的提问来源于stack exchange,提问作者André Lourenço
相关产品推荐
相关产品推荐

