The class itself calls in the init method a get_credentials method, which does I need to mock. Using unittest for mocking;
from unittest import TestCase, mock
from src.layer.utils.db import Db
@singleton
class Db:
def __init__(self):
self.get_credentials()
def get_credentials(self):
# stuff
pass
#Tried and failed:
@mock.patch('src.layer.utils.db.Db.get_credentials',get_creds_mock)
@mock.patch.object(Db, 'get_credentials', get_credentials_mock)
class DbMock:
def get_credentials(self):
pass
def get_credentials_mock(self):
pass
class TestDb(TestCase):
@mock.patch.object(Db, 'get_credentials', get_credentials_mock)
def test_init(self):
db = Db()
self.assertIsInstance(db, Db)
The code of the @singleton decorator class:
def singleton(cls):
instances = {}
def instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return instance
I need to mock the get_credentials function because it communicates with a server, which is not allowed in testing environment. So, I must return the json token itself.
Is there any feasible approach to mock that function?
You could use a solution like https://pypi.org/project/singleton-decorator/ which tackles exactly your problem.
if you cannot exchange the singleton decorator, because it is some kind of framework solution, with this particular solution you are stranded, because you cannot access the instances dictionary.
If you cannot for any reason use another package, but can modify your definition of the singleton wrapper, you could add this to your singleton code:
def singleton(cls):
instances = {}
def instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
instance.__wrapped__ = cls
return instance
and then you should be able to override as presented in the package:
@mock.patch('wherever.Db.__wrapped__.get_credentials')