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

如何模拟会修改调用方逻辑所需参数的函数

问题描述

我需要模拟一个会修改可变参数的函数,且该参数的修改对代码正确执行至关重要。参考代码如下:

import os
from unittest.mock import patch

def mutate_my_dict(mutable_dict):
    if os.path.exists("a.txt"):
        mutable_dict["new_key"] = "new_value"
        return True

def function_under_test():
    my_dict = {"key": "value"}
    if mutate_my_dict(my_dict):
        return my_dict["new_key"]
    return "No Key"

注意:我知道这个例子里可以直接mockos.path.exists,但这只是示例,我有意要模拟mutate_my_dict而非外部模块。我也阅读过unittest.mock相关文档,但似乎不适用于我的场景。

我当前的测试代码无法正常工作,因为mock后的函数没有修改传入的字典,导致断言失败:

def test_function_under_test():
    with patch("__main__.mutate_my_dict") as mutate_my_dict_mock:
        mutate_my_dict_mock.return_value = True
        result = function_under_test()
    assert result == "new_value"
解决方案

要让mock函数修改传入的可变参数,你需要利用side_effect定义mock的自定义行为,而不是仅设置return_value。side_effect可以接收一个函数,该函数会在mock被调用时执行,你可以在其中修改传入的参数:

from unittest.mock import patch

def test_function_under_test():
    def mock_mutate_dict(mutable_dict):
        # 模拟原函数的行为:修改传入的字典
        mutable_dict["new_key"] = "new_value"
        return True

    with patch("__main__.mutate_my_dict", side_effect=mock_mutate_dict) as mutate_my_dict_mock:
        result = function_under_test()
        assert result == "new_value"

或者更简洁地用lambda表达式实现:

def test_function_under_test():
    with patch("__main__.mutate_my_dict") as mutate_my_dict_mock:
        # 用lambda定义side_effect,修改传入的字典并返回True
        mutate_my_dict_mock.side_effect = lambda d: d.update({"new_key": "new_value"}) or True
        result = function_under_test()
        assert result == "new_value"

原理说明:side_effect指定的函数会在mock被调用时执行,接收原函数的参数。这里我们在mock函数里直接修改传入的字典,然后返回True,完全模拟了原函数mutate_my_dict在文件存在时的行为,这样function_under_test就能正确获取到修改后的键值,断言通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:35:22