Mockito如何mock可下标访问的类完成ConfigParser单元测试
mockito框架下实现mock对象支持下标访问返回预设值
核心问题点
原代码存在两个导致测试失败的问题:
- Python中
obj[key]的下标访问本质是调用魔法方法obj.__getitem__(key),mockito默认生成的Dummy对象未配置该方法规则,直接访问会抛出TypeError: 'Dummy' object is not subscriptable;原写法when(parser[section]).thenReturn(settings)会在配置阶段就触发下标访问,此时规则还未生效,直接报错。 - 测试中手动创建的
parsermock对象是测试函数内的局部变量,被测函数get_config()会自行实例化新的ConfigParser对象,根本不会用到这个手动创建的mock实例,需要先对类做补丁替换。
实现方法
- 使用mockito的
patch能力替换configparser模块下的ConfigParser类,拦截被测函数中的类实例化操作 - 针对mock实例的
__getitem__方法配置匹配规则,当传入SETTINGS作为键时,返回预设的配置字典 - 可选增加方法调用校验,确认
read方法被传入正确的ini文件路径
完整可运行代码
from configparser import ConfigParser from unittest import TestCase from mockito import when, mock, verify, patch section = "SETTINGS" # 被测函数 def get_config(): ini_file = "settings.ini" parser = ConfigParser() parser.read(ini_file) settings = parser[section] db_name = settings['db_name'] db_type = settings['db_type'] return (db_name, db_type) class MyTest(TestCase): def test_0_check_get_config(self): expected_db_name = 'test.sqlite' expected_db_type = 'sqlite' expected_ini_path = "settings.ini" settings = { 'db_name': expected_db_name, 'db_type': expected_db_type } # 补丁替换ConfigParser类 with patch('configparser.ConfigParser') as mock_parser_cls: # 生成mock实例,配置类实例化时返回该mock对象 mock_parser = mock(ConfigParser) when(mock_parser_cls).__call__().thenReturn(mock_parser) # 配置下标访问规则:访问[section]时返回预设配置字典 when(mock_parser).__getitem__(section).thenReturn(settings) # 执行被测逻辑 db_name, db_type = get_config() # 结果断言 assert db_name == expected_db_name assert db_type == expected_db_type # 可选:校验read方法调用符合预期 verify(mock_parser).read(expected_ini_path)
扩展说明
- 如果需要支持多个键的下标返回,只需要追加多条
when(mock_obj).__getitem__(目标键).thenReturn(对应返回值)规则即可 - 如果不需要严格匹配键名,可以用mockito自带的通配符
...代替具体键值,即when(mock_parser).__getitem__(...).thenReturn(settings),此时任意下标访问都会返回预设值
内容的提问来源于stack exchange,提问作者chm
相关产品推荐
相关产品推荐

