首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python模拟补丁不模拟对象

Python模拟补丁不模拟对象
EN

Stack Overflow用户
提问于 2022-09-24 09:10:10
回答 1查看 35关注 0票数 0

我正在使用python模拟库,我不知道为什么会得到这个结果。为什么只有第二个被嘲笑,而不是第一个?做这件事最好的方法是什么?

代码语言:javascript
复制
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()

输出

代码语言:javascript
复制
my_func <class 'requests.sessions.Session'>
my_func2 <class 'unittest.mock.Mock'>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-24 09:35:56

这是Python名称空间的一个微妙之处。在第一个my_func()中,您只使用了Session (在使用from requests import Session将其导入模块命名空间之后)。在my_func2()中,您使用requests.Session

@patch('requests.Session')正在取代requests模块中的Session,因此requests.Session将成为模拟对象。但它并不能取代每个模块中对Session的所有引用--事实上,这在Python中是非常困难的。

实际上,在一个基本的层面上,patch()所做的只是设置requests.Session = Mock()。但是要替换模块的全局命名空间中已经存在的对Session的引用,它还必须设置globals()['Session'] = Mock()

换句话说,您必须在正确的命名空间中修补对象。

如果您有一些模块foo.py,其中包含:

代码语言:javascript
复制
from requests import Session

def my_func():
    s = Session()
    ...

然后,一个单独的测试模块test_foo.py (您想在其中模拟Session类)必须在foo的名称空间中对它进行修补,如下所示:

代码语言:javascript
复制
import foo

@patch('foo.Session', ...)
def test_my_func():
    ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73835997

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档