You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/Django/DRF/Pytest中如何实现Laravel Http::fake()功能?

在Django测试中模拟全局HTTP请求(替代Laravel的Http::fake())

为什么requests_mock达不到预期?

requests_mock默认只作用于测试函数的局部上下文,如果你在**应用内部代码(比如视图、服务类、模型方法)**里发起HTTP请求,它不会拦截这些请求,因为它们不在测试函数的mock作用域内。

实现全局HTTP请求模拟的两种方案

方案1:用requests_mock挂载全局适配器

把mock适配器绑定到requests的全局会话上,就能拦截所有位置发起的requests请求:

from django.test import TestCase
import requests
import requests_mock

class ExternalAPITest(TestCase):
    def setUp(self):
        # 创建全局mock适配器
        self.mock_adapter = requests_mock.Adapter()
        # 挂载到requests的默认会话,支持http和https协议
        requests.Session.mount('http://', self.mock_adapter)
        requests.Session.mount('https://', self.mock_adapter)

    def test_mocked_third_party_request(self):
        # 配置mock规则:匹配指定请求地址和方法,返回模拟响应
        self.mock_adapter.register_uri(
            'GET',
            'https://third-party-api.com/user-info',
            json={'id': 1, 'name': 'Mocked User'},
            status_code=200
        )

        # 调用依赖第三方API的DRF接口
        response = self.client.get('/api/user-profile/')

        # 断言接口返回的第三方数据符合模拟结果
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()['user_name'], 'Mocked User')

方案2:用responses库(更简洁的全局拦截)

responses库默认全局拦截所有requests请求,用装饰器即可快速启用:

import responses
from django.test import TestCase

class ExternalAPITest(TestCase):
    @responses.activate
    def test_simplified_mock(self):
        # 添加mock规则
        responses.add(
            responses.POST,
            'https://third-party-api.com/submit',
            json={'status': 'success'},
            status=201
        )

        # 调用内部发起POST请求的接口
        response = self.client.post('/api/submit-data/', {'content': 'test'}, format='json')

        self.assertEqual(response.json()['external_status'], 'success')

针对DRF内部API调用的模拟

如果你的代码是调用项目内部的DRF API端点,不需要mock外部请求,直接用APIClient本身模拟即可:

def test_internal_api_dependency(self):
    # 先模拟内部API的响应
    self.client.post('/api/internal-config/', {'max_limit': 10}, format='json')

    # 调用依赖该内部接口的视图
    response = self.client.get('/api/limited-data/')

    # 断言返回结果符合内部配置的限制
    self.assertEqual(len(response.json()['data']), 10)

注意事项

  • 若使用异步HTTP库(如aiohttp),需用对应mock工具(如aioresponses),原理一致,都是全局拦截请求。
  • 所有mock规则会在测试结束后自动重置,不会影响其他测试用例。

内容的提问来源于stack exchange,提问作者Kamaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:20:42