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

如何在Django/Python中Mock返回响应的URL路径?

几种可行的实现方案

方案1:直接拦截requests.get调用(最简便)

不用搭建真实服务器,直接用unittest.mock拦截指定URL的请求,返回预设的mock响应即可。

示例代码:

import json
from unittest.mock import patch
import requests
import pytest

# 你的待测试函数
def get_some_data(api_url, **kwargs):
    headers = kwargs.get("headers", {})
    params = kwargs.get("params", {})
    response = requests.get(api_url, headers=headers, params=params)
    return response

# 你的mock响应生成函数(补全bytes编码细节)
def mock_response(data):
    response = requests.Response()
    response.status_code = 200
    response._content = json.dumps(data).encode('utf-8')
    return response

# 测试用例
@pytest.mark.parametrize("test_url, mock_data", [
    ("http://mock-api.local/test-data", {"status": "ok", "data": [1,2,3]}),
])
@patch("requests.get")
def test_get_some_data(mock_get, test_url, mock_data):
    # 设定规则:当请求test_url时返回mock响应
    mock_get.return_value = mock_response(mock_data)
    
    # 调用待测试函数
    response = get_some_data(test_url)
    
    # 验证结果
    assert response.status_code == 200
    assert json.loads(response.content) == mock_data
    # 确认requests.get确实用指定URL调用过
    mock_get.assert_called_once_with(test_url, headers={}, params={})

方案2:用Django测试服务器(适合Django项目)

如果是Django项目,直接用Django自带的测试框架启动临时服务器,临时注册一个返回mock数据的视图,就能拿到真实可访问的URL。

示例代码:

from django.http import JsonResponse
from django.urls import path
from django.test import TestCase
import requests
import json

# 你的待测试函数
def get_some_data(api_url, **kwargs):
    headers = kwargs.get("headers", {})
    params = kwargs.get("params", {})
    response = requests.get(api_url, headers=headers, params=params)
    return response

# 临时定义返回mock数据的视图
def mock_api_view(request):
    return JsonResponse({"source": "django-test-server", "data": "mock-content"})

class TestGetSomeData(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        # 临时添加URL路由到项目根URLconf
        from django.conf import settings
        root_urlconf = __import__(settings.ROOT_URLCONF, fromlist=["urlpatterns"])
        cls.temp_route = path("mock-api/", mock_api_view)
        root_urlconf.urlpatterns.append(cls.temp_route)

    @classmethod
    def tearDownClass(cls):
        # 测试结束后清理临时路由
        from django.conf import settings
        root_urlconf = __import__(settings.ROOT_URLCONF, fromlist=["urlpatterns"])
        root_urlconf.urlpatterns.remove(cls.temp_route)
        super().tearDownClass()

    def test_get_some_data(self):
        # 拼接测试服务器的完整URL
        test_url = self.live_server_url + "/mock-api/"
        response = get_some_data(test_url)
        
        assert response.status_code == 200
        assert json.loads(response.content) == {"source": "django-test-server", "data": "mock-content"}

方案3:用Python标准库启动临时HTTP服务器

如果想要真实可访问的URL而非mock拦截,用Python内置的http.server启动临时服务器,测试完成后自动关闭。

示例代码:

import json
import threading
from http.server import BaseHTTPRequestHandler, HTTPServer
import requests
import pytest

# 你的待测试函数
def get_some_data(api_url, **kwargs):
    headers = kwargs.get("headers", {})
    params = kwargs.get("params", {})
    response = requests.get(api_url, headers=headers, params=params)
    return response

# 定义处理请求的类,返回mock数据
class MockRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "application/json")
        self.end_headers()
        self.wfile.write(json.dumps({"source": "std-lib-server", "data": "mock-result"}).encode('utf-8'))

# 定义pytest fixture,自动启动/关闭服务器
@pytest.fixture(scope="function")
def mock_server_url():
    server = HTTPServer(("localhost", 0), MockRequestHandler)
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    
    # 返回服务器完整URL(端口自动分配)
    yield f"http://localhost:{server.server_address[1]}"
    
    # 测试结束后关闭服务器
    server.shutdown()

# 测试用例
def test_get_some_data(mock_server_url):
    response = get_some_data(mock_server_url)
    
    assert response.status_code == 200
    assert json.loads(response.content) == {"source": "std-lib-server", "data": "mock-result"}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:18:18