Reputation: 2607
I have a test module, test_roles.py
which is trying to test the module roles.py
. I want to mock out the use of MongoClient
from pymongo
within the roles module, so that my unit tests do not rely on an external service. The following is a simplified example of what I'm doing that isn't working for me. How do I get this to work so that I can fake out MongoClient
everywhere?
In roles.py
:
from pymongo import MongoClient
client = MongoClient(...)
In test_roles.py
:
import roles
def test_mock():
assert type(roles.client).__name__ == 'FakeMongoClient'
In conftest.py
:
import pytest
import pymongo
@pytest.fixture(autouse=True)
def fake_mongo(monkeypatch):
class FakeMongoClient():
pass
monkeypatch.setattr(pymongo, 'MongoClient', FakeMongoClient)
I don't believe the question identified as a duplicate is asking the same thing. Editing a module's global variable after-the-fact is different from modifying the dependency such that the actions that occur during import use the mocked dependency. In this example, unless the MongoClient
initialization uses lazy connections, failing to mock before first import means we get a failure during import of roles.
Upvotes: 0
Views: 1041
Reputation: 532003
roles.py
uses roles.MongoClient
, not pymongo.MongoClient
, to define roles.client
, due to how you imported the name. You need to patch the same:
monkeypatch.setattr(roles, 'MongoClient', FakeMongoClient)
Your original patch should work if roles.py
looked like
import pymongo
client = pymongo.MongoClient()
Upvotes: 3