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

Python Mock Patch未生效问题:为何仅第二个函数被Mock?

关于unittest.mock未正确Mock requests.Session的问题解析

问题现象

执行测试代码后,my_func中的Session未被Mock,而my_func2中的Session被成功Mock:

测试代码

import unittest
from unittest.mock import patch, Mock

import requests
from requests import Session


def my_func():
    s = Session()
    print('my_func', type(s))


def my_func2():
    s = requests.Session()
    print('my_func2', type(s))


class Test(unittest.TestCase):

    @patch("requests.Session", new=Mock)
    def test1(self, *args):
        my_func()

    @patch("requests.Session", new=Mock)
    def test2(self, *args):
        my_func2()

输出结果

my_func <class 'requests.sessions.Session'>
my_func2 <class 'unittest.mock.Mock'>

原因分析

核心原因是unittest.mock.patch作用的是对象被引用的位置,而非定义位置:

  • my_func2直接调用requests.Session,patch("requests.Session")会替换requests模块内的Session引用,因此生效;
  • my_func使用的是从requests导入到当前模块的Session,这个引用在导入阶段就绑定到了当前模块的命名空间,patch("requests.Session")修改的是requests模块内的对象,不会影响当前模块已导入的Session引用。

正确的Mock实现方式

有两种可行方案:

方案1:Patch当前模块的Session引用

针对当前模块中导入的Session进行patch(假设当前脚本为入口文件,用__main__.Session;若为命名模块,替换为模块名,比如my_module.Session):

import unittest
from unittest.mock import patch, Mock

import requests
from requests import Session


def my_func():
    s = Session()
    print('my_func', type(s))


def my_func2():
    s = requests.Session()
    print('my_func2', type(s))


class Test(unittest.TestCase):
    @patch("__main__.Session", new=Mock)
    def test1(self, *args):
        my_func()

    @patch("requests.Session", new=Mock)
    def test2(self, *args):
        my_func2()

方案2:统一函数内的引用方式

修改my_func,让它也使用requests.Session的调用方式,这样只需patchrequests.Session即可同时覆盖两个函数:

def my_func():
    # 改用requests.Session()而非直接使用导入的Session
    s = requests.Session()
    print('my_func', type(s))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 18:40:49