Python中如何mock多个文件的open、read、write操作以编写单元测试?
解决方法
之前代码触发无限递归的原因是:patch builtins.open 后,mock函数内部调用的open已经被替换为自定义的mock函数本身,匹配到非目标文件时就会反复调用自己。
解决核心思路是提前保存未被修改的原生open函数引用,非目标文件的读写请求全部转交给原生open处理,三个目标文件单独走mock逻辑,同时可以捕获写入文件的内容做结果断言。以下是完整的单元测试实现示例:
import unittest from unittest import mock from lib.filesum import FileSum class TestFileSum(unittest.TestCase): def test_save_sum(self): # 提前保存原生open函数引用,避免递归 original_open = open # 用来存储第三个文件的写入内容,用于后续断言 write_content = None def custom_open(filename, mode='r', *args, **kwargs): nonlocal write_content # mock第一个读文件a.txt if filename == "a.txt": return mock.mock_open(read_data="3").return_value # mock第二个读文件b.txt elif filename == "b.txt": return mock.mock_open(read_data="2").return_value # mock第三个写文件sum.txt,拦截write操作 elif filename == "sum.txt": mock_file = mock.mock_open().return_value def save_write_content(content): nonlocal write_content write_content = content mock_file.write = save_write_content return mock_file # 其他所有文件走原生open逻辑,不受影响 else: return original_open(filename, mode, *args, **kwargs) with mock.patch("builtins.open", new=custom_open): fs = FileSum("a.txt", "b.txt", "sum.txt") fs.save_sum() # 断言求和写入结果正确 self.assertEqual(write_content, "5") if __name__ == '__main__': unittest.main()
如果你使用pytest框架,只需要调整测试用例的写法即可,mock逻辑完全一致。
内容的提问来源于stack exchange,提问作者nickponline
相关产品推荐
相关产品推荐

