如何在python中模拟@singleton装饰类中的方法



类本身在init方法中调用一个get_credentials方法,我需要模拟它。使用unittest进行嘲讽;

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

我需要模拟get_credentials函数,因为它与服务器通信,这在测试环境中是不允许的。因此,我必须返回json令牌本身。

有什么可行的方法来模拟这个功能吗?

您可以使用这样的解决方案https://pypi.org/project/singleton-decorator/它正好解决了你的问题。

如果您不能交换singleton decorator,因为它是某种框架解决方案,那么与这个特定的解决方案相比,您将陷入困境,因为您无法访问实例字典。

如果由于任何原因不能使用另一个包,但可以修改单例包装器的定义,则可以将其添加到单例代码中:

def singleton(cls):
instances = {}

def instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
instance.__wrapped__ = cls
return instance

然后你应该能够覆盖包中显示的内容:

@mock.patch('wherever.Db.__wrapped__.get_credentials')

最新更新