pythonunit-testingmockingpymongopytest-mock

How to mock mongo with python


How to create a mocked mongo db object to test my software using python?
I tried https://pytest-mock-resources.readthedocs.io/en/latest/mongo.html but got error.
First, i tried the code below:

def insert_into_customer(mongodb_connection):
    collection = mongodb_connection['customer']
    to_insert = {"name": "John", "address": "Highway 37"}
    collection.insert_one(to_insert)


from pytest_mock_resources import create_mongo_fixture
mongo = create_mongo_fixture()

def test_insert_into_customer(mongo):
    insert_into_customer(mongo)

    collection = mongo['customer']
    returned = collection.find_one()

    assert returned == {"name": "John", "address": "Highway 37"}


test_insert_into_customer(mongo)

I got the error below:

Traceback (most recent call last):
  File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 19, in <module>
    test_insert_into_customer(mongo)
  File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 11, in test_insert_into_customer
    insert_into_customer(mongo)
  File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 2, in insert_into_customer
    collection = mongodb_connection['customer']
TypeError: 'function' object is not subscriptable

And then i tried the code:

def insert_into_customer(mongodb_connection):
    collection = mongodb_connection['customer']
    to_insert = {"name": "John", "address": "Highway 37"}
    collection.insert_one(to_insert)


from pymongo import MongoClient
from pytest_mock_resources import create_mongo_fixture

mongo = create_mongo_fixture()


def test_create_custom_connection(mongo):
    client = MongoClient(**mongo.pmr_credentials.as_mongo_kwargs())
    db = client[mongo.config["database"]]

    collection = db["customers"]
    to_insert = [
        {"name": "John"},
        {"name": "Viola"},
    ]
    collection.insert_many(to_insert)

    result = collection.find().sort("name")
    returned = [row for row in result]

    assert returned == to_insert


test_create_custom_connection(mongo)

and got the error:

Traceback (most recent call last):
  File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 30, in <module>
    test_create_custom_connection(mongo)
  File "/home/ehasan-karbasian/Desktop/NationalEliteFoundation/serp_matcher/src/mock_mongo.py", line 14, in test_create_custom_connection
    client = MongoClient(**mongo.pmr_credentials.as_mongo_kwargs())
AttributeError: 'function' object has no attribute 'pmr_credentials'

It looks like mongo is a function not a MongoClient.
How can i use the library pytest_mock_resources to mock mongo?
Is there a better library to mock monodb to test with pytest?


Solution

  • import mongomock
    client = mongomock.MongoClient()
    database = client.__getattr__(database_name)
    collection = database.__getattr__(collection_name)
    

    You can define as many as client, database and collections you need at the same time.