如何mock返回类实例的属性变量,解决Python单元测试mock报错
解决方法
方案1:直接替换实例的tileindex属性(最简便)
不需要处理patch路径问题,创建BaseLayer实例后直接覆盖self.tileindex为你构造的Mock对象即可:
from unittest.mock import Mock from folder.layer.base import BaseLayer def test_register(): # 1. 实例化待测类 layer = BaseLayer() # 2. 创建Mock对象代替tileindex实例 mock_tileindex = Mock() # 3. 配置Mock的方法返回值,解决下标访问报错 # 你的代码中需要调用bulk_add后取返回值的下标,所以显式设置返回的字典结构 test_identifier = "test_file_id" mock_tileindex.bulk_add.return_value = {test_identifier: True} # 其他用到的tileindex方法也可以按需配置返回值,比如: # mock_tileindex.get_key.return_value = "test_key" # 4. 直接替换实例的tileindex属性 layer.tileindex = mock_tileindex # 5. 构造测试前置数据 layer.items = [ {"register_status": True, "identifier": test_identifier}, {"register_status": True, "identifier": "another_file_id"} ] # 6. 调用待测方法,执行断言 status = layer.register() assert status == True # 可选:验证方法调用是否符合预期 mock_tileindex.bulk_add.assert_called_once()
方案2:正确Mock load_plugin函数
如果需要在实例化前就替换tileindex的生成逻辑,可以按Mock哪里用就Patch哪里的规则,patch BaseLayer所在模块导入的load_plugin:
from unittest.mock import Mock, patch from folder.layer.base import BaseLayer # 注意Patch的路径是folder.layer.base.load_plugin,即BaseLayer导入load_plugin的路径 @patch("folder.layer.base.load_plugin") def test_register_with_patch(mock_load_plugin): # 配置load_plugin的返回值为Mock的tileindex实例 mock_tileindex = Mock() test_identifier = "test_file_id" mock_tileindex.bulk_add.return_value = {test_identifier: True} mock_load_plugin.return_value = mock_tileindex # 此时实例化BaseLayer,self.tileindex会自动替换为Mock对象 layer = BaseLayer() layer.items = [ {"register_status": True, "identifier": test_identifier}, {"register_status": True, "identifier": "another_file_id"} ] status = layer.register() assert status == True
报错原因说明
- 之前的
TypeError: 'Mock' object is not subscriptable是因为Mock对象的方法默认返回新的Mock实例,本身不支持[]下标访问,只要显式给对应的方法设置return_value为你需要的可下标结构(字典、列表等)即可解决。 - 之前的
AttributeError是因为Patch路径错误,如果你要patch tileindex对应的类,需要写全路径到类名(比如folder.tileindex.base.TileIndexClass),但这种方案需要额外处理实例化逻辑,不如上面两种方案简便。
内容的提问来源于stack exchange,提问作者PhilippeTh
相关产品推荐
相关产品推荐

