如何在pytest中Mock返回None的空HTTPS响应?及相关疑问
解决方案
一、Mock出json()返回None的响应
你之前的错误在于使用了json=json.dumps(None),requests_mock的json参数会自动将传入的Python对象序列化为JSON字符串,你传json.dumps(None)相当于把字符串"null"再次序列化,最终解析后得到的是字符串'null'而非None。正确的实现方式有两种:
方式1:直接传入json=None
如果第三方API返回的是JSON格式的null(而非完全空的响应体),直接给requests_mock.get()传json=None即可:
requests_mock.get(BASE_URL + '/spaghetti', json=None)
此时response.json()会直接返回Python的None,因为None序列化为JSON是null,解析后会还原为None。
方式2:Mock响应对象的json()方法
如果实际场景是完全空的响应体(无任何内容),调用response.json()原本会抛出JSONDecodeError,但你的代码可能捕获了该异常并返回None。这种情况可以直接Mock响应对象的json方法:
def test_retry_on_empty_response(requests_mock): # 先Mock一个空响应体 requests_mock.get(BASE_URL + '/spaghetti', text='') # 重写响应对象的json方法,让它返回None mock_resp = requests_mock.last_request.response mock_resp.json = lambda: None # 执行你的业务代码 result = your_business_function() # 断言重试逻辑生效或结果符合预期
二、为何无状态码、无内容的响应不会导致HTTPS库完全报错
- HTTPS的核心是加密传输通道,只要TCP连接成功建立并完成SSL握手,HTTPS层面的“连接”就已经完成,服务器后续是否发送完整的HTTP响应属于应用层(HTTP)的问题,不会直接触发HTTPS库的致命错误。
requests依赖的urllib3在处理不完整的HTTP响应时,会创建一个响应对象,其中状态码可能为None或默认值,响应体为空。此时不会直接抛出异常,直到你尝试解析响应体(比如调用json())时,才可能触发JSONDecodeError。- 你代码中出现的
AttributeError,是因为你捕获了JSONDecodeError并返回了None,后续调用None.get('data')才触发的错误,而非HTTPS库本身报错。
内容的提问来源于stack exchange,提问作者charmingduchess
相关产品推荐
相关产品推荐

