我正在使用python模拟库,我不知道为什么会得到这个结果。为什么只有第二个被嘲笑,而不是第一个?做这件事最好的方法是什么?
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'>发布于 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,其中包含:
from requests import Session
def my_func():
s = Session()
...然后,一个单独的测试模块test_foo.py (您想在其中模拟Session类)必须在foo的名称空间中对它进行修补,如下所示:
import foo
@patch('foo.Session', ...)
def test_my_func():
...https://stackoverflow.com/questions/73835997
复制相似问题