如何使用unittest模拟文件读取方法测试read类的read_file函数
修正后的Read类与单元测试实现
首先先修正原Read类的问题(语法错误、无实际读取逻辑、硬编码路径等),让它具备可测试性:
import os class Read: def __init__(self, file_path): self.file_path = file_path def read_file(self): result = None if os.path.isfile(self.file_path): result = [] try: # 使用with语句自动管理文件资源,避免手动关闭遗漏 with open(self.file_path, "r") as file: result = file.readlines() except Exception as e: raise Exception(f"reading file error {self.file_path} - {str(e)}") else: raise Exception(f"no such file error {self.file_path}") return result
正确的单元测试代码
使用unittest结合mock模块,覆盖三种核心场景:文件存在读取成功、文件不存在、文件存在但读取失败:
import unittest from unittest import mock # 替换成你的Read类所在的模块名 from your_module import Read class TestReadFile(unittest.TestCase): def test_read_file_success(self): # 模拟文件存在且读取正常的场景 test_content = "20000, 00000000, 10000, xyz\n" test_file_path = "c:/user/file.txt" # 模拟os.path.isfile返回True(文件存在) with mock.patch('os.path.isfile', return_value=True): # 模拟open方法返回指定内容 with mock.patch('builtins.open', mock.mock_open(read_data=test_content)): reader = Read(test_file_path) result = reader.read_file() # 验证读取结果是否符合预期 self.assertEqual(result, [test_content]) # 验证open方法是否被正确调用 mock_open = mock.patch('builtins.open').start() mock_open.assert_called_once_with(test_file_path, 'r') mock_open.stop() def test_read_file_not_exist(self): # 模拟文件不存在的场景 test_file_path = "c:/user/file.txt" with mock.patch('os.path.isfile', return_value=False): reader = Read(test_file_path) # 验证是否抛出正确的异常 with self.assertRaises(Exception) as exc_context: reader.read_file() self.assertEqual(str(exc_context.exception), f"no such file error {test_file_path}") def test_read_file_failure(self): # 模拟文件存在但读取失败(如权限问题)的场景 test_file_path = "c:/user/file.txt" error_msg = "Permission denied" with mock.patch('os.path.isfile', return_value=True): # 让open方法抛出IOError with mock.patch('builtins.open', side_effect=IOError(error_msg)): reader = Read(test_file_path) with self.assertRaises(Exception) as exc_context: reader.read_file() # 验证异常信息是否正确 self.assertIn(f"reading file error {test_file_path}", str(exc_context.exception)) self.assertIn(error_msg, str(exc_context.exception)) if __name__ == '__main__': unittest.main()
原测试代码的问题说明
- 变量名
read_file与方法名冲突,导致逻辑混乱 mock.mock_open的read_data参数需要传入字符串,而非列表- 原
read类未定义__init__方法,直接read("filename")实例化会报错 - 断言逻辑错误:尝试调用列表
read_file()会触发TypeError
内容的提问来源于stack exchange,提问作者jhonD
相关产品推荐
相关产品推荐

