Переписал почти все тесты
feat: улучшено логирование и обработка скорингов в PostService и RagApiClient - Добавлены отладочные сообщения для передачи скорингов в функции обработки постов. - Обновлено логирование успешного получения скорингов из RAG API с дополнительной информацией. - Оптимизирована обработка скорингов в функции get_text_message для улучшения отладки. - Обновлены тесты для проверки новых функциональных возможностей и обработки ошибок.
This commit is contained in:
164
tests/test_decorators.py
Normal file
164
tests/test_decorators.py
Normal file
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Тесты для декораторов group и private handlers (error_handler).
|
||||
"""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from aiogram import types
|
||||
|
||||
from helper_bot.handlers.group.decorators import error_handler as group_error_handler
|
||||
from helper_bot.handlers.private.decorators import (
|
||||
error_handler as private_error_handler,
|
||||
)
|
||||
|
||||
|
||||
class FakeMessage:
|
||||
"""Класс-маркер, чтобы мок проходил isinstance(..., types.Message) в декораторе."""
|
||||
pass
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestGroupErrorHandler:
|
||||
"""Тесты для error_handler из group/decorators."""
|
||||
|
||||
async def test_success_returns_result(self):
|
||||
"""При успешном выполнении возвращается результат функции."""
|
||||
@group_error_handler
|
||||
async def sample_handler():
|
||||
return "ok"
|
||||
|
||||
result = await sample_handler()
|
||||
assert result == "ok"
|
||||
|
||||
async def test_exception_is_reraised(self):
|
||||
"""При исключении оно пробрасывается дальше."""
|
||||
@group_error_handler
|
||||
async def failing_handler():
|
||||
raise ValueError("test error")
|
||||
|
||||
with pytest.raises(ValueError, match="test error"):
|
||||
await failing_handler()
|
||||
|
||||
@patch("helper_bot.handlers.group.decorators.logger")
|
||||
async def test_exception_is_logged(self, mock_logger):
|
||||
"""При исключении вызывается logger.error."""
|
||||
@group_error_handler
|
||||
async def failing_handler():
|
||||
raise RuntimeError("logged error")
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
await failing_handler()
|
||||
mock_logger.error.assert_called_once()
|
||||
assert "logged error" in mock_logger.error.call_args[0][0]
|
||||
assert "failing_handler" in mock_logger.error.call_args[0][0]
|
||||
|
||||
@patch("helper_bot.handlers.group.decorators.types")
|
||||
@patch("helper_bot.utils.base_dependency_factory.get_global_instance")
|
||||
@patch("helper_bot.handlers.group.decorators.logger")
|
||||
async def test_exception_sends_to_important_logs_when_message_has_bot(
|
||||
self, mock_logger, mock_get_global, mock_types
|
||||
):
|
||||
"""При исключении и наличии message с bot отправляется сообщение в important_logs."""
|
||||
mock_types.Message = FakeMessage
|
||||
message = MagicMock()
|
||||
message.__class__ = FakeMessage
|
||||
message.bot = MagicMock()
|
||||
message.bot.send_message = AsyncMock()
|
||||
mock_bdf = MagicMock()
|
||||
mock_bdf.settings = {"Telegram": {"important_logs": "-100123"}}
|
||||
mock_get_global.return_value = mock_bdf
|
||||
|
||||
@group_error_handler
|
||||
async def failing_handler(msg):
|
||||
assert msg is message
|
||||
raise ValueError("error for logs")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await failing_handler(message)
|
||||
|
||||
mock_get_global.assert_called_once()
|
||||
message.bot.send_message.assert_called_once()
|
||||
call_kwargs = message.bot.send_message.call_args[1]
|
||||
assert call_kwargs["chat_id"] == "-100123"
|
||||
call_text = call_kwargs["text"]
|
||||
assert "error for logs" in call_text
|
||||
assert "failing_handler" in call_text
|
||||
assert "Traceback" in call_text
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestPrivateErrorHandler:
|
||||
"""Тесты для error_handler из private/decorators."""
|
||||
|
||||
async def test_success_returns_result(self):
|
||||
"""При успешном выполнении возвращается результат функции."""
|
||||
@private_error_handler
|
||||
async def sample_handler():
|
||||
return 42
|
||||
|
||||
result = await sample_handler()
|
||||
assert result == 42
|
||||
|
||||
async def test_exception_is_reraised(self):
|
||||
"""При исключении оно пробрасывается дальше."""
|
||||
@private_error_handler
|
||||
async def failing_handler():
|
||||
raise TypeError("private error")
|
||||
|
||||
with pytest.raises(TypeError, match="private error"):
|
||||
await failing_handler()
|
||||
|
||||
@patch("helper_bot.handlers.private.decorators.logger")
|
||||
async def test_exception_is_logged(self, mock_logger):
|
||||
"""При исключении вызывается logger.error."""
|
||||
@private_error_handler
|
||||
async def failing_handler():
|
||||
raise KeyError("key missing")
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
await failing_handler()
|
||||
mock_logger.error.assert_called_once()
|
||||
assert "key missing" in mock_logger.error.call_args[0][0]
|
||||
|
||||
@patch("helper_bot.handlers.private.decorators.types")
|
||||
@patch("helper_bot.utils.base_dependency_factory.get_global_instance")
|
||||
async def test_exception_sends_to_important_logs_when_message_has_bot(
|
||||
self, mock_get_global, mock_types
|
||||
):
|
||||
"""При исключении и наличии message с bot отправляется сообщение в important_logs."""
|
||||
mock_types.Message = FakeMessage
|
||||
message = MagicMock()
|
||||
message.__class__ = FakeMessage
|
||||
message.bot = MagicMock()
|
||||
message.bot.send_message = AsyncMock()
|
||||
mock_bdf = MagicMock()
|
||||
mock_bdf.settings = {"Telegram": {"important_logs": "-100456"}}
|
||||
mock_get_global.return_value = mock_bdf
|
||||
|
||||
@private_error_handler
|
||||
async def failing_handler(msg):
|
||||
raise RuntimeError("private runtime")
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
await failing_handler(message)
|
||||
|
||||
mock_get_global.assert_called_once()
|
||||
message.bot.send_message.assert_called_once()
|
||||
call_kwargs = message.bot.send_message.call_args[1]
|
||||
assert call_kwargs["chat_id"] == "-100456"
|
||||
call_text = call_kwargs["text"]
|
||||
assert "private runtime" in call_text
|
||||
assert "failing_handler" in call_text
|
||||
|
||||
async def test_no_message_in_args_no_send(self):
|
||||
"""Если в args нет Message, send_message не вызывается (только логирование)."""
|
||||
@private_error_handler
|
||||
async def failing_handler():
|
||||
raise ValueError("no message")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await failing_handler()
|
||||
# get_global_instance не должен вызываться, т.к. message не найден в args
|
||||
Reference in New Issue
Block a user