如何使用pytest测试读取多个文件的Python类?
测试文件读取方法的Mock实现
要在没有实际文件的环境中测试Example.load()方法,你可以用Python标准库的unittest.mock模块来mock内置的open函数,让它根据不同的文件名返回预设内容。下面提供两种可行方案:
方案一:根据文件名返回对应内容(推荐)
这种方式不依赖文件读取顺序,更健壮,能准确匹配不同文件的内容:
# test_example.py from lib import Example from unittest.mock import patch import io def test_example_class(): p_contents = 'abc' q_contents = 'def' # 自定义mock的open函数,根据文件名返回对应内容的模拟文件句柄 def mock_open(filename, *args, **kwargs): if filename == 'p.txt': return io.StringIO(p_contents) elif filename == 'q.txt': return io.StringIO(q_contents) # 遇到未预期的文件时抛出异常,避免测试漏判 raise ValueError(f"Unexpected file: {filename}") # 使用patch临时替换内置的open函数 with patch('builtins.open', side_effect=mock_open): ex = Example() assert ex.load() == p_contents + q_contents
说明
io.StringIO用来模拟文本文件句柄,调用read()时会返回传入的字符串内容。side_effect让mock的open函数根据传入的文件名返回不同结果,完全模拟真实场景。patch的with语句确保mock只在测试代码块内生效,不影响其他逻辑。
方案二:按调用顺序返回内容(简单但依赖顺序)
如果能保证代码中读取文件的顺序固定(先p.txt后q.txt),可以直接按顺序返回模拟的文件对象:
# test_example.py from lib import Example from unittest.mock import patch, MagicMock def test_example_class(): p_contents = 'abc' q_contents = 'def' # 创建两个模拟文件对象,分别设置read()的返回值 mock_p_file = MagicMock() mock_p_file.read.return_value = p_contents mock_q_file = MagicMock() mock_q_file.read.return_value = q_contents # 按调用顺序传递模拟对象 with patch('builtins.open', side_effect=[mock_p_file, mock_q_file]): ex = Example() assert ex.load() == p_contents + q_contents
说明
side_effect传入列表时,mock函数会按顺序返回列表中的每个元素,对应两次open调用的返回值。- 缺点是如果代码中文件读取顺序改变,测试会失败,适合逻辑固定的简单场景。
内容的提问来源于stack exchange,提问作者nickponline
相关产品推荐
相关产品推荐

