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

如何使用side_effect模拟requests.get().url?附代码测试需求

如何用side_effect模拟requests.get().url完成Swapi API调用函数的测试

问题描述

我编写了以下Python函数,用于循环调用Swapi的人物列表API,收集所有请求的URL直到API返回非200状态码。同时编写了测试函数,但需要用side_effect模拟requests.get().url和响应状态码来完成离线测试,避免真实调用API:

from http import HTTPStatus
import requests

def consuming_api_swapi_index_page(initial_page: int = 1):
    """Swapi index page."""
    check = HTTPStatus.OK
    results = []
    while check == HTTPStatus.OK:
        response = requests.get(
            f'https://swapi.dev/api/people/?page={initial_page}'
        )
        results.append(url := response.url)
        print(url)
        check = response.status_code
        initial_page += 1
    return results


def test_consuming_api_swapi_index_page() -> None:
    """Test it."""
    values = [
        'https://swapi.dev/api/people/?page=1',
        'https://swapi.dev/api/people/?page=2',
        'https://swapi.dev/api/people/?page=3',
        'https://swapi.dev/api/people/?page=4',
        'https://swapi.dev/api/people/?page=5',
        'https://swapi.dev/api/people/?page=6',
        'https://swapi.dev/api/people/?page=7',
        'https://swapi.dev/api/people/?page=8',
        'https://swapi.dev/api/people/?page=9',
        'https://swapi.dev/api/people/?page=10',
    ]

    assert consuming_api_swapi_index_page() == values

解决方案

可以通过unittest.mock的patch装饰器结合side_effect来模拟requests.get的返回值,按顺序返回预设的响应对象,控制每个响应的url和status_code,从而让函数按预期执行并终止循环。

修改后的测试代码

from unittest.mock import patch, Mock
from http import HTTPStatus
# 替换为你的函数所在模块名
from your_module import consuming_api_swapi_index_page

def test_consuming_api_swapi_index_page() -> None:
    """Test the API consuming function with mocked requests."""
    expected_urls = [
        'https://swapi.dev/api/people/?page=1',
        'https://swapi.dev/api/people/?page=2',
        'https://swapi.dev/api/people/?page=3',
        'https://swapi.dev/api/people/?page=4',
        'https://swapi.dev/api/people/?page=5',
        'https://swapi.dev/api/people/?page=6',
        'https://swapi.dev/api/people/?page=7',
        'https://swapi.dev/api/people/?page=8',
        'https://swapi.dev/api/people/?page=9',
        'https://swapi.dev/api/people/?page=10',
    ]

    # 构建模拟响应列表:前10个返回200状态和对应URL,最后一个返回404终止循环
    mock_responses = []
    for url in expected_urls:
        resp = Mock()
        resp.url = url
        resp.status_code = HTTPStatus.OK
        mock_responses.append(resp)
    
    # 添加终止循环的非200响应
    final_response = Mock()
    final_response.status_code = HTTPStatus.NOT_FOUND
    mock_responses.append(final_response)

    # 模拟requests.get,按顺序返回预设的响应对象
    with patch('requests.get', side_effect=mock_responses):
        result = consuming_api_swapi_index_page()
        assert result == expected_urls

关键说明

  1. Mock响应对象:每个Mock()实例模拟requests.get返回的响应对象,设置url属性匹配预期请求地址,status_code控制循环的执行逻辑。
  2. side_effect的作用:当requests.get被调用时,会按mock_responses列表的顺序依次返回每个Mock对象。前10次调用返回200状态,函数会将对应URL加入结果列表并继续循环;第11次调用返回404状态,循环终止。
  3. 路径正确的patch:patch('requests.get')需要确保路径正确,如果你的函数是在某个模块中导入requests,则需要patch该模块中的requests.get(比如from mymodule import requests的话,要patchmymodule.requests.get)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:20:38