我有连接到 MongoDB 客户端的代码,我正在尝试对其进行测试。为了测试,我不想连接到实际的客户端,所以我试图找出一个假的来进行测试。代码的基本流程是我在某处有一个函数来创建一个pymongo
客户端,然后对其进行查询并制作一个在其他地方使用的字典。
我想使用 pytest 编写一些测试,这些测试将测试将调用的不同函数和类get_stuff
。我的问题是实际连接到数据库的get_stuff
调用。mongo()
我试图只使用pytest.fixture(autouse=True)
和mongomock.MongoClient()
替换mongo()
.
但这并不能取代mongo_stuff.mongo()
. 有什么方法可以告诉 pytest 替换一个函数,以便fixture
调用我的而不是实际的函数?我认为使fixture
我的测试mongo()
在命名空间中的优先级高于实际模块中的函数。
这是我的示例的示例文件结构:
.
├── project
│ ├── __init__.py
│ ├── mongo_stuff
│ │ ├── __init__.py
│ │ └── mongo_stuff.py
│ └── working_class
│ ├── __init__.py
│ └── somewhere_else.py
└── testing
├── __init__.py
└── test_stuff.py
mongo_stuff.py
import pymongo
def mongo():
return pymongo.MongoClient(connection_params)
def get_stuff():
db = mongo() # Makes the connection using another function
stuff = query_function(db) # Does the query and makes a dict
return result
某处_else.py
from project.mongo_stuff import mongo_stuff
mongo_dict = mongo_stuff.get_stuff()
test_stuff.py
import pytest
import mongomock
@pytest.fixture(autouse=True)
def patch_mongo(monkeypatch):
db = mongomock.MongoClient()
def fake_mongo():
return db
monkeypatch.setattr('project.mongo_stuff.mongo', fake_mongo)
from poject.working_class import working_class # This starts by calling project.mongo_stuff.mongo_stuff.get_stuff()
这目前会给我一个连接错误,因为mongo_stuff.py只在生产环境中工作connection params
。如果我将test_stuff.py中的语句放入测试函数中,那么它可以正常工作,并且db 将用于测试环境。我也尝试将其更改为也不起作用。import
mongomock
setattr
monkeypatch.setattr('project.working_class.mongo_stuff.mongo', fake_mongo)