"""日志配置测试(T-003)。""" import logging import tempfile import unittest from pathlib import Path from unittest import mock from src import logging_config from src.logging_config import _FORMAT, _ContextDefaultsFilter, get_task_logger class LoggingTest(unittest.TestCase): def test_task_logger_carries_context(self): log = get_task_logger("T9", "pay") self.assertEqual(log.extra["task_id"], "T9") self.assertEqual(log.extra["step"], "pay") def test_format_tolerates_missing_context(self): """非任务日志(无 task_id/step)也能格式化,不抛 KeyError。""" record = logging.LogRecord("x", logging.INFO, __file__, 1, "msg", None, None) _ContextDefaultsFilter().filter(record) out = logging.Formatter(_FORMAT).format(record) self.assertIn("task=-", out) self.assertIn("step=-", out) def test_setup_logging_idempotent(self): with tempfile.TemporaryDirectory() as tmp: with mock.patch.object(logging_config, "LOG_FILE", Path(tmp) / "app.log"): logging_config._configured = False logging.getLogger().handlers.clear() logging_config.setup_logging() first = len(logging.getLogger().handlers) logging_config.setup_logging() # 第二次应无操作 self.assertEqual(len(logging.getLogger().handlers), first) # 还原全局 logging 状态,避免影响其它测试 logging.getLogger().handlers.clear() logging_config._configured = False if __name__ == "__main__": unittest.main()