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

Mock对象不可迭代报错:ParserManner类pytest测试问题咨询

解决pytest测试中TypeError: 'Mock' object is not iterable的问题

待测试的Python类

class ParserManner():
    def __init__(self, **kwargs):
        self.file_path = kwargs.get('file_path', None)
        self.soup = kwargs.get('soup', None)
        self.observations = []
        self.ap_path = kwargs.get('ap_path', 'testy/ap.xml')
        self.plugin_map_path = kwargs.get('plugin_map_path', 'testy/plugin_map.csv')
    
    @classmethod
    def load(cls, file_name) -> 'ParserManner':
        file_path = None
        try:
            # some code here
            pass
        except:
            raise RuntimeError("Unable to load soup")
        
        return ParserManner(file_path=file_path, soup=soup)

    def parse(self, soup) -> list['Orange']:
        try:
            # 此处逻辑会遍历soup或调用其返回可迭代对象的方法
            pass
        except:
            pass

现有测试代码

步骤1:初始化实例方法

def setup_instance():
    instance = ParserManner()
    instance.ap_path = 'some_path'
    instance.plugin_map_path = 'some_path'
    instance.file_path = 'some_path'
    instance.observations = []
    return instance

步骤2:测试方法

def test_open_file_success():
    with patch('builtins.open', mock_open(read_data='<assessment-plan></assessment-plan>')) as mock_file:
        instance = setup_instance()
        instance.parse(Mock())
        mock_file.assert_called_once_with('some_path', 'r')

问题描述

运行上述测试代码时抛出错误:TypeError: 'Mock' object is not iterable

解决方案

错误原因

parse方法内部逻辑会尝试遍历传入的soup对象,或调用soup的某个返回可迭代内容的方法(比如BeautifulSoup的find_all),但默认的Mock()对象没有实现迭代相关的魔法方法,也没有模拟这些方法的返回值,导致触发类型错误。

具体修复方式

方式1:让Mock对象支持迭代

给Mock添加__iter__方法,使其返回一个空迭代器:

def test_open_file_success():
    with patch('builtins.open', mock_open(read_data='<assessment-plan></assessment-plan>')) as mock_file:
        instance = setup_instance()
        mock_soup = Mock()
        # 模拟迭代行为,返回空迭代器
        mock_soup.__iter__ = Mock(return_value=iter([]))
        instance.parse(mock_soup)
        mock_file.assert_called_once_with('some_path', 'r')

方式2:模拟实际soup的方法返回可迭代内容

如果parse方法是通过调用soup.find_all等方法获取可迭代结果,直接模拟对应方法的返回值:

def test_open_file_success():
    with patch('builtins.open', mock_open(read_data='<assessment-plan></assessment-plan>')) as mock_file:
        instance = setup_instance()
        mock_soup = Mock()
        # 模拟find_all返回空列表(可迭代)
        mock_soup.find_all.return_value = []
        instance.parse(mock_soup)
        mock_file.assert_called_once_with('some_path', 'r')

方式3:使用真实的BeautifulSoup实例测试

如果测试场景允许,直接用测试数据创建真实的soup对象,更贴近实际运行逻辑:

from bs4 import BeautifulSoup

def test_open_file_success():
    with patch('builtins.open', mock_open(read_data='<assessment-plan></assessment-plan>')) as mock_file:
        instance = setup_instance()
        # 创建真实的soup实例
        test_soup = BeautifulSoup('<assessment-plan></assessment-plan>', 'xml')
        instance.parse(test_soup)
        mock_file.assert_called_once_with('some_path', 'r')

内容的提问来源于stack exchange,提问作者Tes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:28:14