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
相关产品推荐
相关产品推荐

