【问题标题】:Mock a api response模拟一个 api 响应
【发布时间】:2020-08-17 11:55:19
【问题描述】:

背景

我有一个名为 submit_health 的函数,它负责对我们传递的一些数据执行 POST 请求。预期的输出总是如下形式:

{
    "errors": [],
    "warnings": [],
    "success": true
} 

唯一的区别是,在某些情况下,如果我们发送无效数据,"success": false 是可能的,当然“错误”和“警告”会有适当的文字说明为什么没有成功的发布请求。

代码

   def submit_health(health_data):
        return _post_json("health-single", health_data)


def _post_json(resource: str, data: Dict) -> PostResponse:
    json_data = json.dumps(data, default=json_encoding_decimal_default)
    response = request_session_with_retry().post(
        f"{SITE_API_ROOT}/v3/{resource}",
        auth=("", SITE_API_V3_KEY),
        data=json_data,
        headers={"Content-Type": "application/json", "User-Agent": USER_AGENT},
    )
    response.raise_for_status()
    try:
        return json.loads(response.text)
    except Exception:
        return None

问题

我正在尝试使用 pytest 测试 submit_health 函数。我不关心 API 的实现,因为代码的不同部分正在处理该测试。我只关心用预期的输出来测试它

{
    "errors": [],
    "warnings": [],
    "success": true
} 

我的问题是如何模拟此响应?我很想提出任何建议。我读了一些关于猴子补丁的文章,但我不太确定如何模拟响应。我很想得到一些指导。

【问题讨论】:

    标签: python pytest


    【解决方案1】:

    假设您的函数位于 health.py 模块中,我将使用代码创建一个 test_health.py 模块:

    from unittest.mock import Mock, patch
    
    from health import submit_health
    
    
    @patch("health.request_session_with_retry")
    def test_submit_health(request_mock):
        response_mock = Mock(text='{"errors": [], "warnings": [], "success": true}')
        request_mock.return_value.get.return_value = response_mock
    
        result = submit_health({"foo": "bar"})
    
        assert result == {"errors": [], "warnings": [], "success": True}
    
    1. @patch 将修补后的函数作为我命名为 request_mock 的参数传递
    2. 我们需要知道调用 request_session_with_retry.get 时该模拟将返回的内容

    【讨论】:

    • @bigbounty 你有什么理由推荐上下文管理器?
    猜你喜欢
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2014-10-14
    • 2014-05-09
    • 2020-02-04
    • 2023-02-07
    • 2018-04-21
    • 1970-01-01
    相关资源
    最近更新 更多