使用unittest patch断言os.makedirs的文件夹创建路径时出现匹配失败问题
使用unittest patch断言os.makedirs的文件夹创建路径时出现匹配失败问题
我一眼就看出问题出在哪了——你在测试断言里多传了一个511参数,但实际调用os.makedirs的时候根本没显式传递这个值!
问题根源
os.makedirs的mode参数默认值确实是十进制的511(对应八进制0o777),但当你在代码里只写os.makedirs(路径)时,Python会自动使用默认值,但mock的调用记录里只会显式记录你实际传递的参数,不会把默认参数也追加进去。
你看用assert_called_once得到的错误输出,调用记录是call(WindowsPath('...')),完全没有第二个参数,这就和你写的assert_any_call(a, 511)完全不匹配,自然会断言失败。
解决方案
把断言里的511去掉就行,直接断言路径参数:
for a in assertions: mkdirs_mock.assert_any_call(a)
如果你特别想验证mode参数确实使用了默认的511(比如担心后续代码修改时不小心改了默认值),可以结合mock.call来做更严谨的检查:
from unittest.mock import call for a in assertions: # 检查调用记录里包含该路径的调用 assertIn(call(a), mkdirs_mock.call_args_list)
额外优化建议
你的测试可以不用手动收集所有路径,直接复用生产代码的遍历逻辑,减少重复代码的维护成本:
@patch("os.makedirs") def test_base_folders(self, mkdirs_mock): # 先模拟unity_project文件夹存在,避免触发异常 with patch("os.path.exists", return_value=True): sessions.generate_base_folders() # 和生产代码一致的遍历逻辑,自动生成预期路径 for category in ["characters", "environments", "ui", "cinematics"]: for tag in ["concept", "model", "animation", "vfx", "sfx", "vo", "music"]: session_path = Path.cwd() / "sessions" / category / "common" / tag unity_path = Path.cwd() / "unity_project" / "Assets" / category / "common" / tag mkdirs_mock.assert_any_call(session_path) mkdirs_mock.assert_any_call(unity_path) # 顺便验证总调用次数是否正确:4个分类 *7个标签 *2个路径 =56次 self.assertEqual(mkdirs_mock.call_count, 56)
这样以后如果分类或标签有调整,测试代码会自动同步,不用手动更新断言列表。
备注:内容来源于stack exchange,提问作者wavesinaroom
相关产品推荐
相关产品推荐

