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

Python单元测试中后续测试的Mock为何无法覆盖前置测试的Mock?

问题解决:批量运行Python单元测试时Mock失效

问题根源

你的main.py在模块加载阶段就创建了全局的s3实例:

# main.py
s3 = boto3.client('s3')  # 模块导入时执行

第一次测试导入src.main时,boto3.client已被Patch,生成的s3是第一个测试的Mock对象。由于Python模块是单例的,后续测试即使重启Patch,src.main不会重新加载,里面的s3始终是第一次的Mock,和你在setUp中创建的新self.mock_s3不是同一个对象,导致修改新Mock的返回值不生效。

修复方案

方案一:修改业务代码(推荐)

延迟s3实例的创建,让每次调用main()时都重新获取客户端,确保Patch能覆盖:

# main.py
import boto3

def main():
    s3 = boto3.client('s3')  # 函数内部创建,每次调用都会执行
    return s3.list_buckets()

方案二:不修改业务代码,在测试中刷新模块

在测试基类的setUp中重新加载src.main,强制模块级代码重新执行:

# test_base.py
import unittest
from unittest.mock import MagicMock, patch
import importlib
import src.main

class TestBase(unittest.TestCase):
    def setUp(self):
        self.patch_boto3_client = patch('boto3.client', autospec=True)
        self.mock_boto3_client = self.patch_boto3_client.start()

        self.mock_s3 = MagicMock()
        self.mock_boto3_client.side_effect = lambda service: {
            's3': self.mock_s3,
        }[service]
        
        # 重新加载main模块,让s3实例重新创建
        importlib.reload(src.main)

    def tearDown(self) -> None:
        self.patch_boto3_client.stop()

验证效果

修改后重新运行测试:

$ python3 -m coverage run -m unittest test
..
----------------------------------------------------------------------
Ran 2 tests in 0.123s

OK

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:48:21