如何在pytest中Mock类实例?基于给定代码场景求助
问题描述
项目结构如下:
source main_proc.py devinstance.py prodinstance.py requirements.txt host.json
main_proc.py中的get_instance方法根据环境变量创建DevInstance或ProdInstance实例:
def get_instance(self): ins = None env = os.getenv('env', 'dev') if env == 'dev': ins = DevInstance() else: ins = ProdInstance() return ins
DevInstance类(devinstance.py)示例代码:
class DevInstance: def __init__(self): self.eh_client = dict() self.initialize() def initialize(self): try: client = EventHubProducerClient.from_connection_string( conn_str=self.secrets_dict[value], eventhub_name=names[i], http_proxy=HTTP_PROXY ) except Exception as e: logging.error(e) raise e
尝试测试get_instance时Mock整个DevInstance类实例,测试代码如下:
@mock.patch("devinstance.DevInstance") def test_get_instance(self, devins): # Act devins.return_value = MagicMock() result = get_instance() # Assert assert result is not None
需要指导如何正确实现这一Mock操作?
正确Mock实现方案
1. 修正Mock路径
Python的Mock是基于被测试代码实际引用的对象路径生效的。get_instance在main_proc.py中导入并使用DevInstance,所以必须Mockmain_proc模块内的DevInstance引用,而非原始的devinstance.DevInstance。
修改装饰器路径:
@mock.patch("main_proc.DevInstance")
2. 简化Mock实例配置
mock.patch传入的参数(如mock_dev_class)本身就是类Mock对象,它的return_value默认就是MagicMock实例,无需手动赋值。如果需要定制Mock实例的属性/方法,直接操作return_value即可:
@mock.patch("main_proc.DevInstance") def test_get_instance(self, mock_dev_class): # 可选:定制Mock实例的属性 mock_instance = mock_dev_class.return_value mock_instance.eh_client = {"test_key": "test_value"} # 执行被测试方法 result = get_instance() # 断言 mock_dev_class.assert_called_once() # 确认DevInstance被实例化一次 assert result is mock_instance # 确认返回的是Mock实例 assert result is not None
3. 隔离环境变量影响
测试时建议临时设置环境变量,避免污染全局环境。可以用mock.patch.dict临时修改os.environ:
@mock.patch("main_proc.DevInstance") @mock.patch.dict(os.environ, {'env': 'dev'}) def test_get_instance_dev(self, mock_dev_class): result = get_instance() mock_dev_class.assert_called_once() assert isinstance(result, MagicMock) @mock.patch("main_proc.ProdInstance") @mock.patch.dict(os.environ, {'env': 'prod'}) def test_get_instance_prod(self, mock_prod_class): result = get_instance() mock_prod_class.assert_called_once() assert isinstance(result, MagicMock)
4. 规避真实初始化逻辑
通过Mock整个DevInstance类,实例化时不会执行真实的__init__和initialize方法,完全用Mock替代,避免测试依赖外部资源(如EventHub连接)。
内容的提问来源于stack exchange,提问作者user3625533
相关产品推荐
相关产品推荐

