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

Flask路由测试中Mock与Patch配置失败问题排查

问题:Flask路由测试中Mock/Patch未生效导致断言失败

现象

路由代码:

from flask import current_app
from utils.linked_list_handler import get_ll
import json

@detail_bp.route("/get_base_details", methods=["GET"])
def get_all_base_details():
    """Get the details of all nodes with the q_type 'base'"""
    ll = get_ll(current_app)
    base_list=ll.getByQType("base")
    return json.dumps(base_list)

测试代码运行后报错:

FAILED backend/tests/test_details.py::TestGetBaseDetails::test_get_some_base_details - AssertionError: assert [] == ['q_detail_1', 'q_detail_2']

同时mock_get_ll.assert_called_once()和mock_ll.assert_called_once()均提示从未被调用。

原因分析

  1. Patch路径错误:测试中patch的是backend.routes.blueprints.details.get_ll,但路由函数里实际调用的是从utils.linked_list_handler导入的get_ll。根据unittest.mock的规则,必须patch被测试代码实际引用的对象路径,也就是原始模块中的get_ll,而非导入后的副本。
  2. 错误的断言:mock_ll.assert_called_once()是无效的,因为mock_ll是我们创建的Mock实例,并没有被调用过;应该断言的是getByQType方法的调用情况。

修正后的测试代码

class TestGetBaseDetails:
    def test_get_some_base_details(self, test_client: FlaskClient, mocker):
        """
        GIVEN a Flask app configured for testing
        WHEN the '/get_base_details' route is requested with the
        'GET' method while there is a linked list with at least
        one Node with a Question with a q_type of "base"
        THEN check that the response shows the q_detail of those
        base questions
        """
        # 修正patch路径:patch原始模块中的get_ll
        mock_get_ll = mocker.patch("utils.linked_list_handler.get_ll")
        # 创建mock的linked list实例
        mock_ll = mocker.Mock()
        mock_ll.getByQType.return_value = ["q_detail_1", "q_detail_2"]
        # 指定get_ll返回这个mock实例
        mock_get_ll.return_value = mock_ll

        response = test_client.get("/get_base_details")
        assert response.status_code == 200
        assert json.loads(response.data) == ["q_detail_1", "q_detail_2"]

        # 断言get_ll被调用,且参数是current_app
        mock_get_ll.assert_called_once_with(current_app)
        # 断言getByQType被调用,参数是"base"
        mock_ll.getByQType.assert_called_once_with("base")

关键说明

  • Patch路径必须指向被测试代码中实际使用该函数的模块路径,如果路由文件是从utils.linked_list_handler导入get_ll,就需要patchutils.linked_list_handler.get_ll,而不是路由模块里的导入副本。
  • 针对Mock对象的方法调用断言,要直接对该方法进行断言,而非Mock实例本身。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:46:09