如何为接收文件路径参数的Python方法编写单元测试并Mock文件读取
如何为文件操作方法编写Python单元测试并Mock文件读取?
嘿,作为Python新手能想到给方法写单元测试真的超棒!先帮你提个小问题:你的代码里json.dumps(fd)用错啦——dumps是把Python对象转成JSON字符串,这里要读取文件里的JSON内容应该用json.load(fd);另外Python3里print需要加括号,先把原代码修正一下,方便后续测试:
import json class A: def read_json(self, file_json_path): try: with open(file_json_path) as fd: content = json.load(fd) # 替换成load才是读取JSON return content # 最好返回解析后的内容,方便测试验证 except IOError: print(f'exception while opening a file {file_json_path}\n') # Python3的格式化写法
接下来咱们一步步实现单元测试,用Python标准库的unittest和unittest.mock就能搞定,不用额外装包~
1. 核心思路:Mock文件操作
我们不需要真的创建测试文件,而是用mock模块替换系统的open函数,让它返回我们预设的内容或者抛出指定异常,这样就能隔离文件系统的影响,专注测试方法本身的逻辑。
2. 完整测试代码示例
把测试代码放到单独的文件(比如test_a.py)里,内容如下:
import unittest from unittest.mock import patch, mock_open from your_module import A # 替换成你的原代码所在的模块名 import json class TestAReadJson(unittest.TestCase): def test_read_json_success(self): # 第一步:准备测试用的JSON数据 test_json_data = {"name": "demo", "age": 25} test_json_str = json.dumps(test_json_data) # 转成字符串模拟文件内容 # 第二步:Mock open函数,让它返回预设的JSON字符串 with patch('builtins.open', mock_open(read_data=test_json_str)) as mock_file: obj = A() result = obj.read_json("test_file.json") # 第三步:验证结果和调用行为 self.assertEqual(result, test_json_data) # 确保解析后的内容正确 mock_file.assert_called_once_with("test_file.json") # 确保open用了正确的路径 def test_read_json_file_not_found(self): # 测试文件不存在的异常场景 with patch('builtins.open') as mock_file: # 让open抛出IOError模拟文件打开失败 mock_file.side_effect = IOError("File not found") # 捕获print的输出,验证异常提示是否正确 with patch('builtins.print') as mock_print: obj = A() obj.read_json("non_existent.json") mock_print.assert_called_once_with(f'exception while opening a file non_existent.json\n') if __name__ == '__main__': unittest.main()
3. 关键知识点解释
mock_open(read_data=...):快速创建模拟的文件对象,直接返回你预设的文本内容,不用手动模拟read方法。patch('builtins.open'):替换全局的open函数,这样你的A类方法里调用的就是Mock后的版本,不会真的去操作文件系统。side_effect:用来让Mock对象抛出异常或者返回多组结果,这里用来模拟文件打开失败的情况。- 验证方法:
assert_called_once_with检查函数是否被正确调用,assertEqual验证返回结果符合预期。
4. 运行测试
在命令行里执行:
python -m unittest test_a.py -v
就能看到测试的详细结果啦~
内容的提问来源于stack exchange,提问作者kumara
相关产品推荐
相关产品推荐

