在单个Python测试方法中能否mock多种类型的requests请求?
完全可以在同一个测试方法中 mock 多种类型的 requests 请求,以下是两种符合 Python 风格的常用方案,优先满足你使用 mock.patch 装饰器的需求。
方案1:叠加 mock.patch 装饰器(推荐,匹配你的需求)
直接叠加多个 @mock.patch 装饰器分别 mock 不同的请求方法即可,注意装饰器对应的 mock 对象参数顺序是从下往上匹配,也就是离测试函数更近的装饰器对应的 mock 对象排在参数列表的前面。
修改后的测试代码如下:
import unittest from unittest import mock from source import source_function class TestCases(unittest.TestCase): # 叠加两个patch装饰器,分别mock post和get @mock.patch("requests.post") @mock.patch("requests.get") def test_source_function(self, mocked_get, mocked_post): # 配置get请求的返回值,补充你缺失的text属性供post拼接url使用 mocked_get.return_value = mock.Mock( status_code=201, text="test_id", json=lambda: {"data": {"id": "test"}} ) # 配置post请求的返回值,可按需自定义属性 mocked_post.return_value = mock.Mock(status_code=200) # 执行被测试函数 source_function() # 可选:添加断言验证调用逻辑符合预期 mocked_get.assert_called_once_with("get_url.com") mocked_post.assert_called_once_with("post_url.com/test_id")
方案2:Mock 底层 requests.request 方法(适合多请求类型场景)
如果你需要 mock 超过3种请求类型(GET/POST/PUT/DELETE等),叠加太多装饰器会显得冗余,此时可以直接 mock 所有请求方法的底层实现 requests.request,通过 side_effect 匹配不同的请求类型和URL返回对应的值,写法更简洁:
class TestCases(unittest.TestCase): @mock.patch("requests.request") def test_source_function(self, mocked_request): # 定义side_effect,根据请求方法、url返回不同的mock值 def mock_request_side_effect(method, url, **kwargs): mock_resp = mock.Mock(status_code=200) if method == "GET" and url == "get_url.com": mock_resp.text = "test_id" mock_resp.json = lambda: {"data": {"id": "test"}} return mock_resp elif method == "POST" and url.startswith("post_url.com/"): mock_resp.status_code = 200 return mock_resp raise ValueError(f"未适配的请求 {method} {url}") mocked_request.side_effect = mock_request_side_effect source_function() # 断言验证请求逻辑 mocked_request.assert_any_call("GET", "get_url.com") mocked_request.assert_any_call("POST", "post_url.com/test_id")
内容的提问来源于stack exchange,提问作者milanbalazs
相关产品推荐
相关产品推荐

