如何mock返回文件的外部API?使用requests-mock编写api_upload单元测试
单元测试完善方案
首先你现有测试的第一个核心问题是mock的请求方法不匹配:原函数用requests.post调用接口,你当前mock的是get方法,完全不会生效。下面是完整的测试实现方案:
前置说明
你已经安装的requests-mock可以直接满足mock接口的需求,额外需要用到Python标准库自带的tempfile生成临时测试文件,不需要提前在本地准备测试文件。
完整测试代码
import tempfile import os import requests from your_module import api_upload # 此处替换为你实际存放api_upload函数的模块名 def test_api_upload(requests_mock): # 1. 配置mock接口,和原函数的POST请求方法对应 mock_expected_url = "https://example.com/processed/test_20240101.png" requests_mock.post( "https://example.com/upload", json={"url": mock_expected_url}, # 模拟接口返回的JSON结构 status_code=200 ) # 2. 构造测试用参数:请求头、临时测试文件 test_headers = {"Authorization": "Bearer test_abc123", "X-Request-Id": "test_123"} # 生成临时文件,测试结束自动销毁 with tempfile.NamedTemporaryFile(suffix=".txt", delete=False) as f: f.write(b"this is test file content") test_file_path = f.name try: # 3. 调用待测试函数 actual_return_url = api_upload(test_file_path, test_headers) # 4. 验证返回结果符合预期 assert actual_return_url == mock_expected_url # 5. 验证请求参数传递正确 received_request = requests_mock.last_request # 验证请求头和传入的一致 assert received_request.headers["Authorization"] == test_headers["Authorization"] assert received_request.headers["X-Request-Id"] == test_headers["X-Request-Id"] # 验证确实上传了文件 assert "file" in received_request.multipart_components finally: # 清理临时文件 os.unlink(test_file_path)
扩展场景测试
如果需要验证异常处理逻辑,可以调整mock的配置即可:
- 要测试接口报错的情况:把
status_code改成400/500,断言函数会抛出对应异常 - 要测试返回值结构异常的情况:把
json改成没有url字段的结构,断言函数会抛出KeyError
另外原函数存在小缺陷:打开的文件没有手动关闭,后续优化建议把open操作放到with上下文里,避免文件句柄泄漏。
内容的提问来源于stack exchange,提问作者Bruce Banner
相关产品推荐
相关产品推荐

