如何在Python请求库中模拟会话?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Python请求库中模拟会话?相关的知识,希望对你有一定的参考价值。

我一直在试图弄清楚如何模拟Python的请求库的会话,但到目前为止还找不到解决方案。这是我需要编写测试的common.py代码:

import requests

def request_url(method, url):
    return _request_url(method, url)

def _request_url(method, url):
    session = requests.session()
    adapter = TlsAdapter(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
    session.mount("https://", adapter)
    return session.request(method, url)
答案

只是模拟整个_request_url函数,而不是打扰会话对象。函数所做的就是提供一个响应对象,模拟该函数并返回一个模拟响应对象。

但是,如果您正在测试_request_url函数本身,那么只需模拟session名称;额外的调用将全部传递给mock。然后,您可以为mocked.return_value.rquest.return_value对象提供所选的响应对象。

所以

from unittest import mock

with mock.patch('requests.session') as mock_session:
    session_instance = mock_session.return_value
    mock_response = session_instance.request.return_value

    response = _request_url('METHOD', 'some url')

    assert response is mock_response
    session_instance.mount.assert_called()
    session_instance.request.assert_called_with('METHOD', 'some url')

或者用TestCase方法:

@mock.patch('requests.session')
def test_request_url(self,  mock_session):
    session_instance = mock_session.return_value
    mock_response = session_instance.request.return_value

    response = _request_url('METHOD', 'some url')

    self.assertTrue(response is mock_response)
    session_instance.mount.assert_called()
    session_instance.request.assert_called_with('METHOD', 'some url')

演示:

>>> from unittest import mock
>>> import requests, ssl
>>> class TlsAdapter:
...     # mocked adapter, just for illustration purposes
...     def __init__(self, *args, **kwargs): pass
...
>>> def _request_url(method, url):
...     session = requests.session()
...     adapter = TlsAdapter(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
...     session.mount("https://", adapter)
...     return session.request(method, url)
...
>>> with mock.patch('requests.session') as mock_session:
...     session_instance = mock_session.return_value
...     mock_response = session_instance.request.return_value
...     response = _request_url('METHOD', 'some url')
...     assert response is mock_response
...     session_instance.mount.assert_called()
...     session_instance.request.assert_called_with('METHOD', 'some url')
...
>>> # nothing happened, because the test passed, no assertion errors were raised
...

以上是关于如何在Python请求库中模拟会话?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android volley 库中使用 cookie

Python 向 Postman 请求代码片段

如何限制请求 python 库中 HTTP 请求的下载速率?

无法在反应测试库中使用模拟服务人员

ruby 我感兴趣的库中的代码片段

利用Python模拟GitHub登录