如何为捕获异常的Python文件删除工具函数编写单元测试?
如何为捕获内部异常的文件删除函数编写单元测试?
你的目标函数如下:
import os import logging def delete_file_name(file_name, logger): """ Deletes given file name """ try: os.remove(file_name) logger.info("Deleted file: %s", file_name) except FileNotFoundError: logger.error("Error: File not found %s", file_name) except PermissionError: logger.error("Invalid permissions while deleting: %s", file_name) except OSError as exc: logger.error("Error while deleting %s: %s", exc.filename, exc.strerror)
你之前的测试报错,核心原因是函数内部已经捕获了所有异常,不会向外抛出,所以assertRaises自然捕获不到。这类函数的测试重点应该放在两个维度:
- 验证
os.remove是否被正确调用 - 验证不同异常场景下,日志是否按预期输出
下面是基于unittest和unittest.mock的完整测试用例:
import unittest from unittest.mock import patch, MagicMock import logging from your_module import delete_file_name # 替换成函数所在的模块名 class TestDeleteFileName(unittest.TestCase): def setUp(self): # 创建模拟logger对象,用于捕获日志调用 self.logger = MagicMock(spec=logging.Logger) @patch('os.remove') def test_delete_success(self, mock_remove): # 测试正常删除场景 test_file = "test.txt" delete_file_name(test_file, self.logger) mock_remove.assert_called_once_with(test_file) self.logger.info.assert_called_once_with("Deleted file: %s", test_file) @patch('os.remove') def test_delete_file_not_found(self, mock_remove): # 测试文件不存在场景 test_file = "missing.txt" mock_remove.side_effect = FileNotFoundError delete_file_name(test_file, self.logger) mock_remove.assert_called_once_with(test_file) self.logger.error.assert_called_once_with("Error: File not found %s", test_file) @patch('os.remove') def test_delete_permission_error(self, mock_remove): # 测试权限不足场景 test_file = "protected.txt" mock_remove.side_effect = PermissionError delete_file_name(test_file, self.logger) mock_remove.assert_called_once_with(test_file) self.logger.error.assert_called_once_with("Invalid permissions while deleting: %s", test_file) @patch('os.remove') def test_delete_generic_os_error(self, mock_remove): # 测试其他OSError场景 test_file = "error.txt" # 构造带属性的OSError实例,匹配函数内的日志输出逻辑 mock_exc = OSError("Permission denied") mock_exc.filename = test_file mock_exc.strerror = "Permission denied" mock_remove.side_effect = mock_exc delete_file_name(test_file, self.logger) mock_remove.assert_called_once_with(test_file) self.logger.error.assert_called_once_with( "Error while deleting %s: %s", mock_exc.filename, mock_exc.strerror ) if __name__ == '__main__': unittest.main()
关键说明:
- 用
MagicMock模拟logger,无需配置真实日志,直接断言info/error方法的调用参数和次数 - 每个测试场景单独控制
os.remove的行为:正常执行或抛出指定异常 - 不需要使用
assertRaises,因为函数内部已吞掉异常,转而验证日志输出和mock函数的调用是否符合预期
内容的提问来源于stack exchange,提问作者iDev
相关产品推荐
相关产品推荐

