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

如何使用TestClient为调用其他端点的FastAPI端点编写单元测试?

如何用TestClient测试内部调用其他端点的FastAPI接口

你的场景里,/spawner端点会通过requests调用同应用内的/create/{index}端点,直接用TestClient测试的话,requests.post会发起真实HTTP请求,而非TestClient的模拟环境。这里提供两种可行的测试方案:

方案一:Mock外部请求(无需修改业务代码)

通过unittest.mock拦截requests.post调用,验证它是否按预期调用了目标端点,不用发起真实请求。

测试代码示例

from fastapi.testclient import TestClient
from unittest.mock import patch, call
import your_module  # 替换为你的实际模块名

client = TestClient(your_module.app)

def test_spawner_endpoint():
    # Mock requests.post方法
    with patch('your_module.requests.post') as mock_post:
        # 发送请求到/spawner
        response = client.post("/spawner")
        
        # 验证/spawner的返回值
        assert response.status_code == 200
        assert response.json() == {"msg": "spawned the creation/update of 4 resources"}
        
        # 验证requests.post被正确调用4次,每次URL符合预期
        expected_calls = [
            call("http://localhost:8000/create/0"),
            call("http://localhost:8000/create/1"),
            call("http://localhost:8000/create/2"),
            call("http://localhost:8000/create/3"),
        ]
        mock_post.assert_has_calls(expected_calls, any_order=False)

方案二:重构代码,直接调用内部逻辑(更贴近真实业务)

如果不想依赖mock,可以重构spawn函数,让它直接调用worker路径操作函数,或者使用TestClient的模拟请求,避免发起真实HTTP请求。

重构后的业务代码

import fastapi
import os

app = fastapi.FastAPI()

service_host = os.environ.get('SERVICE_HOST', 'localhost:8000')

@app.post('/spawner')
def spawn():
    # 直接调用worker函数,替代HTTP请求
    for i in range(4):
        worker(i)
    return {'msg': 'spawned the creation/update of 4 resources'}

@app.post('/create/{index}')
def worker(index: int):
    return {'msg': f'Created/updated resource {index}'}

对应测试代码

from fastapi.testclient import TestClient
import your_module

client = TestClient(your_module.app)

def test_spawner_endpoint():
    # 验证/spawner的返回结果
    response = client.post("/spawner")
    assert response.status_code == 200
    assert response.json() == {"msg": "spawned the creation/update of 4 resources"}
    
    # 可选:单独验证worker端点的逻辑正确性
    for i in range(4):
        worker_response = client.post(f"/create/{i}")
        assert worker_response.status_code == 200
        assert worker_response.json() == {"msg": f"Created/updated resource {i}"}

如果生产环境必须用HTTP调用(比如跨服务场景),可以把HTTP调用逻辑封装成依赖,测试时替换为模拟实现,兼顾业务代码的灵活性和测试的可靠性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:45:40