When I tried to run my test it tries to create a real conection with MongoDB instead of using mongomock.
This stop happening when I remove the "from .main import HashClient" from my init.py.
my project is:
hash_controller/
|
|----> init.py
|----> hash_controller.py
|----> test_hash_controller.py
My init.py is:
`from .main import HashClient`
My hash_controller is:
import hashlib
import json
import os
import time
def get_connection():
_db_user = os.environ["HASH_DB_USER"]
_db_password = os.environ["HASH_DB_PASS"]
_db_host = os.environ["HASH_DB_HOST"]
_db_port = os.environ["HASH_DB_PORT"]
_db_name = os.environ["HASH_DB_NAME"]
_db_collection = os.environ["HASH_DB_COLLECTION"]
# _client = MongoClient(f"mongodb://{_db_user}:{_db_password}@{_db_host}:{_db_port}/")
from pymongo import MongoClient
_client = MongoClient(f"mongodb://{_db_host}:{_db_port}/")
_database = _client[_db_name]
_collection = _database[_db_collection]
return _collection
class HashClient:
@staticmethod
def exist(customer_uuid: str, type: str, obj):
HashClient._check_customer_and_type(customer_uuid, type)
HashClient._check_obj(obj)
id = HashClient._get_hash(customer_uuid, type, obj)
collection = get_connection()
item = collection.find_one(id)
if item is None:
return False
else:
return True
and my test is:
import os
import mongomock
os.environ["HASH_DB_USER"]=""
os.environ["HASH_DB_PASS"]=""
os.environ["HASH_DB_HOST"]="localhost"
os.environ["HASH_DB_PORT"]="27017"
os.environ["HASH_DB_NAME"]="test"
os.environ["HASH_DB_COLLECTION"]="test"
with mongomock.patch(servers=(('localhost', 27017),)):
import pymongo
client = pymongo.MongoClient("localhost")
from .main import HashClient
def test_exist_false():
hash = HashClient._get_hash("123", "user", {"user": "222"})
client["test"]["test"].insert_one({"_id": hash})
response = HashClient.exist("123", "user", {"user": "123"})
assert response == False
client.test.test.delete_many({})
I tried moving all the imports inside the function so they don't get executed when running the test, but anything helps. The idea is to run the test with the import from the init.py
In the last test function
def test_exist_false(), mocked mongoclientwhich is created in thewhitblock is called to save data.client["test"]["test"].insert_one({"_id": hash})It is mocked client, no problem. but
HashClient.exist()does not use it, it even has no access to the mockedclient.Why
HashClient.exist()has not access to mockedclient?because it creates collection itself inside itself. the problem is that the collection which is created in
exist()function is not mocked, it's the real collection.Better to split the file
hash_controller.pyto two files. a file forget_collection()and another one forclass HashClient.HashClientcan set collection in method__init__()orset_collection()or etc.So it will be possible to set the mocked collection for
HashClientin tests.Edit:
setting mock db config in
os.environshould work too. Because the functionget_collection()uses the config after setting it in the test file, I've no idea about imports and about why it doesn't work.But at least to split
hash_controller.pycan increase software cohesion and independence of tests.