New to Python pytest, below are the code snippets which I am using to mock a MongoDB
connection.
My Mongo Connection util, which is used by my all dao layers:
connection_util.py
from pymongo import MongoClient
mongo_connection = MongoClient()
This is one of my DAO layers, used to get student information:
student_dao.py
from connection_util import mongo_connection
class StudentDAO:
def get_student_info(self, student_id):
student_table = mongo_connection['test_db']['student']
student_data = student_table.find_one({"_id": student_id})
return student_data
My pytest conftest
file which contains the mongomock
connection fixture:
conftest.py
import mongomock
import pytest
@pytest.fixture(scope='class', autouse=True)
def patch_mongo():
mongo_connection = mongomock.MongoClient()
yield mongo_connection
mongo_connection.drop_database('mongodb')
mongo_connection.drop_database('testdb')
mongo_connection.close()
My test file. Here I am trying to mock the actual mongo_connection instance with the Mongomock instance:
test_student.py
import connection_util
from student_dao import StudentDAO
@pytest.mark.usefixtures("patch_mongo")
class TestStudent:
def test_student(self, patch_mongo):
with patch.object(connection_util, "mongo_connection", patch_mongo):
student_id = "123546"
student = StudentDAO()
student_data = student.get_student_info("123546")
assert student_id == student_data.get("_id")
In the patch.object
my target is connection_util
, my attribute is mongo_connection
and my new variable is patch_mongo(pytest fixture)
. It successfully mocks my mongo_connection
variable to pymongo MongoClient and it works within the with statement. But in my studentdao.py
it still refers to the pymongo MongoClient instead of mongomock
MongoClient.
When I change the import statement of connection_util in student_dao.py from "from connection_util import mongo_connection"
to "import connection_util"
and change the "mongo_connection"
to "connection_util.mongo_connection"
it is working correctly. Below code works. It replaces the pymongo MongoClient to mongomock MongoClient.
import connection_util
class StudentDAO:
def get_student_info(self, student_id):
student_table = connection_util.mongo_connection['test_db']['student']
student_data = student_table.find_one({"_id": student_id})
return student_data
The issue here is I cannot do these changes to all my DAO layers as there are many files and doing it manually takes more time too. Is there a way to mock the mongo_connection instance without replacing the import statement?