python 在pytest中模拟空的HTTP响应

jhiyze9q  于 2023-09-29  发布在  Python
关注(0)|答案(2)|浏览(118)

我经常使用第三方API,该API间歇性地响应以下原始HTTPS响应:

> GET / HTTP/1.1
> Host: spaghetti.org
> User-Agent: curl/7.64.1
> Accept: */*
>

即没有status_code,没有内容,什么都没有。我正在编写一些代码,当遇到这个响应时,将重试请求多达三次(具有指数回退)。我正在努力模仿pytest中的响应。我在我的代码中看到这个空响应清单是一个AttributeError,它发生在代码之后,如下所示:

response = requests.get('url.com/spaghetti').json()
response.get('data')

这导致

AttributeError: 'NoneType' object has no attribute 'get'

为了创建一个具有相同行为的mock响应(即当调用.json()时返回None),我尝试用这个mock设置我的测试:

requests_mock.get(BASE_URL + '/spaghetti', json=json.dumps(None))

但是,这个模拟的response.json()返回的不是None,而是'null'
有什么建议可以让我模拟这个奇怪的响应,让它返回一个带有.json()方法的对象,该方法返回None?此外,有没有人想到这个响应在HTTPS库中不会完全出错?

u3r8eeie

u3r8eeie1#

这不是一个有效的情况,因为json.loads()永远不会返回None,但是您可以这样做

import requests
import json

def test_empty_http(requests_mock, monkeypatch):
    monkeypatch.setattr(json, "loads", lambda kwargs: None)
    requests_mock.get('http://url', json=None)
    assert requests.get('http://url').json() is None
0sgqnhkj

0sgqnhkj2#

我认为您可能希望将json属性模拟为返回None的匿名函数。试试这个:

requests_mock.get(BASE_URL + '/spaghetti', json=lambda: None)

更新:
我无法重现错误。我建议您在看到这个奇怪的响应对象时尝试将它保存到一个文件中。这样您就可以重新加载resp对象,这应该会给予您带来更多的了解。
范例:

>>> resp = requests.get("http://example.com")
>>> with open("weird_response.pickle", "wb") as f:
...   pickle.dump(resp, f, protocol=pickle.HIGHEST_PROTOCOL)
... 
>>> with open("weird_response.pickle", "rb") as f:
...   unpickled_resp = pickle.load(f)
...
>>> unpickled_resp.json()

相关问题