Python Mock类型标注优化:实现VS Code对requests方法与Mock属性的自动补全
Python Mock类型标注优化:实现VS Code对requests方法与Mock属性的自动补全
我之前也踩过这个坑,VS Code对unittest.mock的类型提示确实不太友好,尤其是mock requests这类第三方库的时候。先把你当前的代码贴出来,方便大家理解问题场景:
@patch("main.requests") def test_get_joke(mock_get_joke): mock_response = MagicMock() mock_response.status_code = 200 mock_response.json.return_value = {"value": "joke"} mock_get_joke.get.return_value = mock_response assert get_joke() == "joke"
你提到用cast和spec没生效,大概率是用法没到位。下面给你几个亲测有效的方案,能让VS Code正确识别类型并提供自动补全:
方案一:create_autospec + 类型包(最推荐)
create_autospec会自动生成带有原类完整类型信息的Mock对象,不仅能触发IDE补全,还能帮你检查属性拼写错误。另外记得先安装requests的类型定义包,让IDE能识别requests的原生类型:
首先安装类型包:
pip install types-requests
然后修改测试代码:
from unittest.mock import patch, create_autospec import requests def get_joke(): # 假设你的业务逻辑是这样的 resp = requests.get("https://api.example.com/jokes") return resp.json()["value"] @patch("main.requests") def test_get_joke(mock_get_joke): # 创建带有requests.Response类型约束的mock对象 mock_response = create_autospec(requests.Response, spec_set=True) mock_response.status_code = 200 mock_response.json.return_value = {"value": "joke"} mock_get_joke.get.return_value = mock_response assert get_joke() == "joke"
这样VS Code就能精准识别mock_response的status_code、json()等属性,也能识别mock_get_joke.get的return_value属性。
方案二:spec + 类型标注(灵活可控)
如果不想用create_autospec,可以手动给MagicMock指定spec参数,再配合cast做类型标注:
from unittest.mock import patch, MagicMock import requests from typing import cast @patch("main.requests") def test_get_joke(mock_get_joke): # 用spec指定mock的原型为requests.Response,再用cast告诉IDE实际类型 mock_response = cast(requests.Response, MagicMock(spec=requests.Response)) mock_response.status_code = 200 mock_response.json.return_value = {"value": "joke"} # 同样给get方法做类型提示 mock_get_joke.get = cast(type(requests.get), mock_get_joke.get) mock_get_joke.get.return_value = mock_response assert get_joke() == "joke"
这种方式更灵活,适合需要自定义mock行为的场景。
方案三:伪造__class__属性(快速临时解决)
如果只是想快速触发补全,不想改太多代码,可以直接给Mock对象指定__class__属性,“欺骗”IDE它是目标类型:
from unittest.mock import patch, MagicMock import requests @patch("main.requests") def test_get_joke(mock_get_joke): mock_response = MagicMock() # 告诉IDE这个mock是requests.Response类型 mock_response.__class__ = requests.Response mock_response.status_code = 200 mock_response.json.return_value = {"value": "joke"} mock_get_joke.get.return_value = mock_response assert get_joke() == "joke"
这种方法简单粗暴,适合临时调试用,但不会做属性校验,容易写出错误的测试代码。
试试上面的方法,应该就能解决VS Code自动补全的问题了!
备注:内容来源于stack exchange,提问作者Oleg
相关产品推荐
相关产品推荐

