You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为捕获异常的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()

关键说明:

  1. 用MagicMock模拟logger,无需配置真实日志,直接断言info/error方法的调用参数和次数
  2. 每个测试场景单独控制os.remove的行为:正常执行或抛出指定异常
  3. 不需要使用assertRaises,因为函数内部已吞掉异常,转而验证日志输出和mock函数的调用是否符合预期

内容的提问来源于stack exchange,提问作者iDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 21:22:23