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

Python单元测试:如何测试会修改入参字典的do_something函数

针对do_something函数的单元测试方案

核心思路是通过mock依赖函数(func_4、func_5)或者直接mock修改para的逻辑,控制is_done的值变化,覆盖do_something里的三个分支逻辑。以下是具体测试场景和实现代码:

测试场景1:func_4返回True,func_1修改is_done为True

此时func_2和func_3都不会被调用,最终para的is_done为True。

from unittest import TestCase, mock
import your_module  # 替换为你的代码所在模块名

class TestDoSomething(TestCase):
    def test_func1_triggers_is_done(self):
        # 构造测试用的para字典(只需包含is_done,其他键可按需添加)
        test_para = {"is_done": False}
        
        # mock func_4返回True,让func_1修改is_done为True
        with mock.patch("your_module.func_4", return_value=True):
            # mock func_2和func_3,验证它们是否被调用
            with mock.patch("your_module.func_2") as mock_func2, mock.patch("your_module.func_3") as mock_func3:
                your_module.do_something(test_para)
                
                # 断言func_2、func_3未被调用
                mock_func2.assert_not_called()
                mock_func3.assert_not_called()
                # 断言is_done被修改为True
                self.assertEqual(test_para["is_done"], True)

测试场景2:func_4返回False,func_5返回True

此时func_1执行后is_done仍为False,func_2会被调用并修改is_done为True,func_3不会被调用。

def test_func2_triggers_is_done(self):
        test_para = {"is_done": False}
        
        with mock.patch("your_module.func_4", return_value=False):
            with mock.patch("your_module.func_5", return_value=True):
                with mock.patch("your_module.func_3") as mock_func3:
                    your_module.do_something(test_para)
                    
                    mock_func3.assert_not_called()
                    self.assertEqual(test_para["is_done"], True)

测试场景3:func_4和func_5都返回False

此时func_1、func_2执行后is_done仍为False,最终会调用func_3。

def test_func3_called_when_all_fail(self):
        test_para = {"is_done": False}
        
        with mock.patch("your_module.func_4", return_value=False):
            with mock.patch("your_module.func_5", return_value=False):
                with mock.patch("your_module.func_3") as mock_func3:
                    your_module.do_something(test_para)
                    
                    # 断言func_3被调用一次
                    mock_func3.assert_called_once()
                    # 断言is_done保持False
                    self.assertEqual(test_para["is_done"], False)

替代方案:直接mock func_1/func_2修改para的逻辑

如果你不需要验证func_4/func_5的调用,只想测试do_something的分支逻辑,可以直接mock func_1和func_2,让它们直接修改传入的para字典:

def test_func1_modifies_para_directly(self):
        test_para = {"is_done": False}
        
        # 自定义mock_func1,直接修改para的is_done为True
        def mock_func1(para):
            para["is_done"] = True
        
        with mock.patch("your_module.func_1", side_effect=mock_func1):
            with mock.patch("your_module.func_2") as mock_func2, mock.patch("your_module.func_3") as mock_func3:
                your_module.do_something(test_para)
                
                mock_func2.assert_not_called()
                mock_func3.assert_not_called()
                self.assertEqual(test_para["is_done"], True)

注意事项

  • 确保mock的路径正确:如果函数在当前模块,使用__main__.func_name;如果在其他模块,使用模块名.func_name。
  • 对于大型字典,测试时只需构造包含is_done键的字典即可,其他键不影响测试逻辑,可省略或随意添加。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:45:51