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

使用mock的side_effect时为何出现StopIteration错误?

问题:Mock Path时触发StopIteration错误

我编写了一个使用Path的函数,尝试通过mock的side_effect为两次Path调用分配不同返回值,但运行测试时报错StopIteration。

被测试函数代码:

def some_function(input_file, file): 
    compressed_file = Path(input_file)
    non_compressed_file = Path(file)

测试代码:

@mock.patch('exchanges.impl.bmex.preprocessing.Path')
def test_choose_MFII_files(mock_Path):
    mock_Path.side_effect = [Path(pd.jobserve_config[BMLL_SECTION][WORK_DIR]+ '/MDPRECVOLTICK_MC_20230703.ZIP'),
                              Path(pd.jobserve_config[BMLL_SECTION][WORK_DIR] + '/MERGED_MDPRECVOLTICK_MC_20230703.ZIP')]

报错信息:

_mock_self = <MagicMock name='Path' id='140495179866752'>, args = (PosixPath('/tmp'), 'MERGED_MDPRECVOLTICK_MC_20230703.ZIP'), kwargs = {}
self = <MagicMock name='Path' id='140495179866752'>, effect = <list_iterator object at 0x7fc7954ae220>

 def _execute_mock_call(_mock_self, *args, **kwargs):
        self = _mock_self
        # separate from _increment_mock_call so that awaited functions are
        # executed separately from their call, also AsyncMock overrides this method
    
        effect = self.side_effect
        if effect is not None:
            if _is_exception(effect):
                raise effect
            elif not _callable(effect):
>               result = next(effect)
E               StopIteration

../../anaconda3/envs/jobserveee/lib/python3.8/site-packages/mock/mock.py:1163: StopIteration

错误原因:

  1. 调用次数超出预设列表长度:你给side_effect传了2个元素的列表,但实际测试中Path被调用的次数超过了2次,列表元素耗尽后迭代器抛出StopIteration。
  2. 真实Path构造触发额外调用:你在side_effect里直接使用了真实的Path()构造函数,而这个操作会触发对被mock的Path的调用(因为你mock的是exchanges.impl.bmex.preprocessing.Path,测试代码中创建真实Path时会调用这个被mock的对象),导致额外增加了调用次数,超出了你预设的2次。

解决办法:

不要在side_effect里使用真实的Path实例,改用模拟对象替代:

@mock.patch('exchanges.impl.bmex.preprocessing.Path')
def test_choose_MFII_files(mock_Path):
    # 创建两个模拟的Path实例
    mock_compressed = mock.Mock()
    mock_non_compressed = mock.Mock()
    
    # 模拟Path的字符串表示(如果函数中用到的话)
    mock_compressed.__str__.return_value = f"{pd.jobserve_config[BMLL_SECTION][WORK_DIR]}/MDPRECVOLTICK_MC_20230703.ZIP"
    mock_non_compressed.__str__.return_value = f"{pd.jobserve_config[BMLL_SECTION][WORK_DIR]}/MERGED_MDPRECVOLTICK_MC_20230703.ZIP"
    
    # 设置side_effect为模拟实例列表
    mock_Path.side_effect = [mock_compressed, mock_non_compressed]
    
    # 调用被测试函数
    some_function("test_input", "test_file")
    
    # 验证调用次数符合预期
    assert mock_Path.call_count == 2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:02:48