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

为何unittest.mock的patch()在multiprocessing子进程中不生效?

unittest.mock.patch在multiprocessing子进程中失效的问题解决

问题原因

multiprocessing的启动方式(fork/spawn)导致mock状态无法跨进程传递:

  • fork:Unix/Linux默认启动方式,子进程会完整复制父进程的内存空间,包括已生效的mock,因此patch能在子进程中正常工作。
  • spawn:macOS(Python3.8+)、Windows默认启动方式,子进程会重新启动Python解释器并重新导入所有模块,父进程中设置的patch不会被继承,因此子进程调用的是原始函数逻辑。

你的本地环境大概率使用spawn启动方式,而CI环境用的是fork,这就是两者行为差异的核心原因。

解决方案

方案1:强制使用fork启动方式(仅Unix/Linux/macOS可用)

修改主进程中创建上下文的代码,指定用fork方式启动子进程:

def main():
    with patch("b.function_to_mock"):
        # 强制使用fork上下文
        context = multiprocessing.get_context('fork')
        process = context.Process(target=run_new_process, args=())
        print("call from the main process")
        call_mocked_function()
        process.start()
        process.join()

这种方式下子进程会直接继承父进程的mock状态,无需修改其他代码即可达到预期效果。

方案2:在子进程内部执行patch

针对spawn启动方式,直接在子进程的目标函数中完成patch操作:
修改b.py中的run_new_process函数:

def run_new_process():
    from unittest.mock import patch
    with patch("b.function_to_mock"):
        print("call from the subprocess")
        function_to_mock()

这样不管启动方式是什么,子进程执行时都会先patch目标函数,避免触发真实逻辑。

方案3:用initializer全局初始化patch

在主进程中定义初始化函数,让子进程启动时自动执行patch:

# 在a.py中添加初始化函数
def init_subprocess():
    from unittest.mock import patch
    # 启动全局patch,在子进程生命周期内持续有效
    patcher = patch("b.function_to_mock")
    patcher.start()

def main():
    with patch("b.function_to_mock"):
        context = multiprocessing.get_context(multiprocessing.get_start_method())
        # 指定子进程初始化函数
        process = context.Process(target=run_new_process, args=(), initializer=init_subprocess)
        print("call from the main process")
        call_mocked_function()
        process.start()
        process.join()

这种方式适合需要在子进程多个函数中复用mock的场景。

验证效果

修改后运行a.py,输出会符合预期:

call from the main process
call from the subprocess

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 20:05:00