如何在 Python 的请求库中模拟会话中的副作用? [英] How to mock side effects in session in Python's request library?

查看:40
本文介绍了如何在 Python 的请求库中模拟会话中的副作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我昨天在提出的问题的后续.

我正在尝试模拟 requests 库的会话.虽然我得到了如何模拟成功返回值的答案,但我仍在尝试弄清楚如何模拟 400、401 或 302 等副作用.

这就是我模拟会话的方式:

<预><代码>>>>从单元测试导入模拟>>>导入请求,ssl>>>类 TlsAdapter:... # 模拟适配器,仅用于说明目的... def __init__(self, *args, **kwargs): 通过...>>>def _request_url(方法, url):... session = requests.session()... 适配器 = TlsAdapter(ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)... session.mount("https://", 适配器)...返回 session.request(method, url)...>>>使用 mock.patch('requests.session') 作为 mock_session:... session_instance = mock_session.return_value... mock_response = session_instance.request.return_value... response = _request_url('METHOD', 'some url')...断言响应是 mock_response... session_instance.mount.assert_call()... session_instance.request.assert_call_with('METHOD', 'some url')

现在,据我所知,我需要模拟 session_instance.request.side_effect.如果我尝试做这样的事情,它会失败:

 response_redirect = mock.MagicMock()response_redirect.status_code = 302response_redirect.headers = {"location": "https://absolute"}session_instance.request.side_effect = response_redirectresponse = _request_url('方法', 'https://absolute')self.assertEqual(结果,响应重定向)#断言错误

解决方案

你不需要副作用.您的重定向"响应只是 session.request 调用的另一个返回值.在 mock_return 参考中设置您的属性:

mock_response = session_instance.request.return_valuemock_response.status_code = 302mock_response.headers = {"location": "https://absolute"}response = _request_url('方法', 'http://absolute')

在需要时使用 .side_effects:

  • 引发异常
  • 处理多个调用(您可以将 side_effects 设置为要生成的返回值序列,按顺序使用).
  • 需要访问传递给调用的值(您可以将 side_effect 设置为将使用相同参数调用的函数).

但是:如果您正在测试的代码是_request_url(),那么请求是否导致重定向或应该无关不是._request_url() 中的代码与返回的响应类型完全无关,那么您为什么要测试呢?

另一方面,如果您正在测试使用 _request_url() 作为实用函数的代码,那么您应该模拟那个函数,而不是 requests 库.

This is a followup to a question that I asked yesterday.

I am trying to mock a session of the requests library. While I got my answer as to how to mock a successful return value, I am still trying to figure out how to mock side effects such as 400, 401, or 302 etc.

This is how I am mocking a session:

>>> 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')

Now, as far as I have read, I need to mock session_instance.request.side_effect. If I try to do something like this, it fails:

    response_redirect = mock.MagicMock()
    response_redirect.status_code = 302
    response_redirect.headers = {"location": "https://absolute"}

    session_instance.request.side_effect = response_redirect
    response = _request_url('METHOD', 'https://absolute')
    self.assertEqual(result, response_redirect)

    #Assertion error

解决方案

You don't need a side effect. Your 'redirect' response is just another return value for the session.request call. Set your attributes on the mock_return reference:

mock_response = session_instance.request.return_value
mock_response.status_code = 302
mock_response.headers = {"location": "https://absolute"}

response = _request_url('METHOD', 'http://absolute')

Use .side_effects for when you need to:

  • raise exceptions
  • handle multiple calls (you can set side_effects to a sequence of return values to produce, used in order).
  • need to have access to the values that have been passed to the call (you can set side_effect to a function that'll be called with the same arguments).

However: if the code you are testing is _request_url(), then it should not matter if the request resulted in a redirect or not. The code in _request_url() is entirely indifferent to what kind of response is being returned, so why should you need to test for that at all?

If, on the other hand you are testing code that uses _request_url() as a utility function, then you should be mocking that function, and not the requests library.

这篇关于如何在 Python 的请求库中模拟会话中的副作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆