如何在Pytest中mock任意路径的文件写入操作,避免真实生成文件
Mock open及文件写入逻辑的实现方案
你可以直接使用Python标准库unittest.mock中的patch和mock_open组合实现需求,不需要触发真实的文件IO操作:
基础实现(单文件写入场景)
from unittest.mock import patch, mock_open # 替换为你自己业务模块的导入,比如你的写文件逻辑在utils.py的save_binary函数中 from your_module import save_binary def test_file_write_logic(): # 初始化mock的open对象 mocked_open = mock_open() # patch全局内置open函数,替换为mock对象 with patch("builtins.open", mocked_open): test_path = "/any/non/exist/path.bin" test_byte_data = [b"part1", b"part2", b"part3"] # 执行业务逻辑 save_binary(test_path, test_byte_data) # 验证open调用参数符合预期 mocked_open.assert_called_once_with(test_path, "wb") # 验证写入内容符合预期 file_handle = mocked_open() expected_content = b"".join(test_byte_data) file_handle.write.assert_called_once_with(expected_content)
多文件写入场景实现
如果业务逻辑中会打开多个不同路径的文件,你可以给mock对象配置side_effect来区分不同路径的调用:
from unittest.mock import patch, mock_open, call from your_module import multi_file_write_logic def test_multi_file_write(): # 存储不同路径对应的mock文件句柄 path_handle_map = {} def open_side_effect(file_path, *args, **kwargs): if file_path not in path_handle_map: path_handle_map[file_path] = mock_open()() return path_handle_map[file_path] with patch("builtins.open", side_effect=open_side_effect) as mocked_open: # 执行业务逻辑 multi_file_write_logic() # 验证指定路径的open调用 target_path = "/target/file/path" mocked_open.assert_has_calls([call(target_path, "wb")], any_order=True) # 验证指定路径的写入内容 target_handle = path_handle_map[target_path] target_handle.write.assert_called_once_with(b"expected content")
注意:mock失效的绝大多数原因是patch路径错误,你需要保证patch的open路径是业务代码实际引用的路径,比如业务代码中用了from builtins import open as custom_open,你需要patch业务模块下的custom_open,而不是全局的builtins.open
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

