You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito如何mock可下标访问的类完成ConfigParser单元测试

mockito框架下实现mock对象支持下标访问返回预设值

核心问题点

原代码存在两个导致测试失败的问题:

  • Python中obj[key]的下标访问本质是调用魔法方法obj.__getitem__(key),mockito默认生成的Dummy对象未配置该方法规则,直接访问会抛出TypeError: 'Dummy' object is not subscriptable;原写法when(parser[section]).thenReturn(settings)会在配置阶段就触发下标访问,此时规则还未生效,直接报错。
  • 测试中手动创建的parser mock对象是测试函数内的局部变量,被测函数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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 15:42:10