Python 在导入类之前对其进行模拟
我试图模拟父类中的一个方法,该方法在任何类方法之外声明。问题是,我不知道如何在父类中实例化LoggerUtils类。由于实现的巨大规模和重构的成本,将其放在一个_uinit__;中不是一个选项Python 在导入类之前对其进行模拟,python,mocking,python-unittest,Python,Mocking,Python Unittest,我试图模拟父类中的一个方法,该方法在任何类方法之外声明。问题是,我不知道如何在父类中实例化LoggerUtils类。由于实现的巨大规模和重构的成本,将其放在一个_uinit__;中不是一个选项 在导入测试类之前,有没有办法模拟父类 导入类时,至少要在加载之前模拟该方法 有没有办法解决导入时加载非惰性方法的问题 我尝试了懒惰的加载方法,但我就是没有让它工作;使用mock库修补所有方法,但方法总是在我可以模拟任何东西之前加载。下面我有一个模拟尝试的例子,但总是调用LoggerUtils 父类:
- 在导入测试类之前,有没有办法模拟父类
- 导入类时,至少要在加载之前模拟该方法
- 有没有办法解决导入时加载非惰性方法的问题
class AbstractApi:
logger = LoggerUtils.get_logger('AbstractApi')
def update(self):
<code>
要测试的类:
api\u映射\u资产\u类型.py
from abstract_api import AbstractApi
class ApiMapAssetType(AbstractApi):
def update(self):
<code>
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
@patch('api_map_asset_type.AbstractApi.LoggerUtils')
@patch('api_map_asset_type.AbstractApi')
def setUp(self, mock2_abstract_loger, mock_3):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
from undetermined_project_library.LoggerUtils import LoggerUtils
with patch.object(LoggerUtils, 'get_logger') as mock_logger:
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
def setUp(self):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
测试等级:
测试\ api \映射\资产\类型.py
from abstract_api import AbstractApi
class ApiMapAssetType(AbstractApi):
def update(self):
<code>
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
@patch('api_map_asset_type.AbstractApi.LoggerUtils')
@patch('api_map_asset_type.AbstractApi')
def setUp(self, mock2_abstract_loger, mock_3):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
from undetermined_project_library.LoggerUtils import LoggerUtils
with patch.object(LoggerUtils, 'get_logger') as mock_logger:
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
def setUp(self):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
已编辑 这是我找到的唯一解决方案,因为我无法在导入之前模拟类属性中的父类或模拟方法,所以我决定在导入之前模拟整个测试,但我认为这不是一个最佳或干净的解决方案: 测试等级: 测试\ api \映射\资产\类型.py
from abstract_api import AbstractApi
class ApiMapAssetType(AbstractApi):
def update(self):
<code>
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
@patch('api_map_asset_type.AbstractApi.LoggerUtils')
@patch('api_map_asset_type.AbstractApi')
def setUp(self, mock2_abstract_loger, mock_3):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
from undetermined_project_library.LoggerUtils import LoggerUtils
with patch.object(LoggerUtils, 'get_logger') as mock_logger:
from unittest import TestCase
from mock imort patch
from api_map_asset_type import ApiMapAssetType
class TestApiMapAssetType(TestCase):
def setUp(self):
self.asset_api = ApiMapAssetType()
@patch('AbstractApi.update')
def test_update(self, mock_parent_update):
mock_orm = MagicMock()
self.asset_api.update()
mock_parent_update.assert_called_with()
如果我了解您的模块布局,这应该可以:
class TestApiMapAssetType(TestCase):
@patch('undetermined_project_library.LoggerUtils')
def setUp(self, mock_abstract_logger):
self.asset_api = ApiMapAssetType()
@patch('api_map_asset_type.ApiMapAssetType.update')
def test_update(self, mock_parent_update):
self.asset_api.update()
mock_parent_update.assert_called_with()
请注意以下几点:
- 您必须从它们定义的库中模拟
;您使用了LoggerUtils
,这是不正确的,因为AbstractApi.LoggerUtils
不属于LoggerUtils
AbstractApi
- 我删除了
的模拟-至少在这个方面你不需要它AbstractApi
为实际调用的方法进行了修补-如果调用基本实现,则使用基类方法可能有意义(不知道是否这样做)update
- 我猜你的一些模块布局-你可能需要调整它
补丁
调用看起来是错误的:您补丁了api\u map\u asset\u type.AbstractApi
,然后是AbstractApi.LoggerUtils
。我尝试了不同的组合来修补这些类,但任何组合都有效。问题是,由于有人在类属性中调用了de Logger类,所以在导入时会调用此方法,因为Python不执行惰性导入。在导入之前,我试图找到一种模拟此方法的方法。因此,在测试中,您在setUp
中调用apimapasettype()
,但您没有导入它-因此我猜您没有显示完整的代码。你们在那里做本地进口吗?请显示一个。好吧,我放置了导入,我尝试将它放在补丁之前/之后,或者用sys.modules加载来伪装它。我还尝试了LazyLoad函数。我仍然认为LoggerUtils
的修补程序不正确-请确保以与访问它相同的方式进行修补-可能是api\u map\u asset\u type.AbstractApi.LoggerUtils
,或者AbstractApi
所在的相应模块。