mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
161 lines
5.5 KiB
Python
161 lines
5.5 KiB
Python
"""Telegram 模块 Mock 工具。
|
|
|
|
提供统一的 Telegram 相关模块 mock 设置,避免在测试文件中重复定义。
|
|
"""
|
|
|
|
import sys
|
|
from unittest.mock import AsyncMock, MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
class MockTelegramNetworkError(Exception):
|
|
"""Mock telegram.error.NetworkError used in tests."""
|
|
|
|
|
|
class MockTelegramForbidden(Exception):
|
|
"""Mock telegram.error.Forbidden used in tests."""
|
|
|
|
|
|
class MockTelegramInvalidToken(Exception):
|
|
"""Mock telegram.error.InvalidToken used in tests."""
|
|
|
|
|
|
def create_mock_telegram_modules():
|
|
"""创建 Telegram 相关的 mock 模块。
|
|
|
|
Returns:
|
|
dict: 包含 telegram 和相关模块的 mock 对象
|
|
"""
|
|
mock_telegram = MagicMock()
|
|
mock_telegram.BotCommand = MagicMock
|
|
mock_telegram.Update = MagicMock
|
|
mock_telegram.constants = MagicMock()
|
|
mock_telegram.constants.ChatType = MagicMock()
|
|
mock_telegram.constants.ChatType.PRIVATE = "private"
|
|
mock_telegram.constants.ChatAction = MagicMock()
|
|
mock_telegram.constants.ChatAction.TYPING = "typing"
|
|
mock_telegram.constants.ChatAction.UPLOAD_VOICE = "upload_voice"
|
|
mock_telegram.constants.ChatAction.UPLOAD_DOCUMENT = "upload_document"
|
|
mock_telegram.constants.ChatAction.UPLOAD_PHOTO = "upload_photo"
|
|
mock_telegram.error = MagicMock()
|
|
mock_telegram.error.BadRequest = Exception
|
|
mock_telegram.error.Forbidden = MockTelegramForbidden
|
|
mock_telegram.error.InvalidToken = MockTelegramInvalidToken
|
|
mock_telegram.error.NetworkError = MockTelegramNetworkError
|
|
mock_telegram.ReactionTypeCustomEmoji = MagicMock
|
|
mock_telegram.ReactionTypeEmoji = MagicMock
|
|
|
|
mock_telegram_ext = MagicMock()
|
|
mock_telegram_ext.ApplicationBuilder = MagicMock
|
|
mock_telegram_ext.ContextTypes = MagicMock()
|
|
mock_telegram_ext.ContextTypes.DEFAULT_TYPE = MagicMock
|
|
mock_telegram_ext.ExtBot = MagicMock
|
|
mock_telegram_ext.filters = MagicMock()
|
|
mock_telegram_ext.filters.ALL = MagicMock()
|
|
mock_telegram_ext.MessageHandler = MagicMock
|
|
|
|
# Mock telegramify_markdown
|
|
mock_telegramify = MagicMock()
|
|
mock_telegramify.markdownify = lambda text, **kwargs: text
|
|
|
|
# Mock apscheduler
|
|
mock_apscheduler = MagicMock()
|
|
mock_apscheduler.schedulers = MagicMock()
|
|
mock_apscheduler.schedulers.asyncio = MagicMock()
|
|
mock_apscheduler.schedulers.asyncio.AsyncIOScheduler = MagicMock
|
|
mock_apscheduler.schedulers.background = MagicMock()
|
|
mock_apscheduler.schedulers.background.BackgroundScheduler = MagicMock
|
|
|
|
return {
|
|
"telegram": mock_telegram,
|
|
"telegram.ext": mock_telegram_ext,
|
|
"telegramify_markdown": mock_telegramify,
|
|
"apscheduler": mock_apscheduler,
|
|
}
|
|
|
|
|
|
@pytest.fixture(scope="module", autouse=True)
|
|
def mock_telegram_modules():
|
|
"""Mock Telegram 相关模块的 fixture。
|
|
|
|
自动应用于使用此 fixture 的测试模块。
|
|
"""
|
|
mocks = create_mock_telegram_modules()
|
|
monkeypatch = pytest.MonkeyPatch()
|
|
|
|
monkeypatch.setitem(sys.modules, "telegram", mocks["telegram"])
|
|
monkeypatch.setitem(sys.modules, "telegram.constants", mocks["telegram"].constants)
|
|
monkeypatch.setitem(sys.modules, "telegram.error", mocks["telegram"].error)
|
|
monkeypatch.setitem(sys.modules, "telegram.ext", mocks["telegram.ext"])
|
|
monkeypatch.setitem(
|
|
sys.modules, "telegramify_markdown", mocks["telegramify_markdown"]
|
|
)
|
|
monkeypatch.setitem(sys.modules, "apscheduler", mocks["apscheduler"])
|
|
monkeypatch.setitem(
|
|
sys.modules, "apscheduler.schedulers", mocks["apscheduler"].schedulers
|
|
)
|
|
monkeypatch.setitem(
|
|
sys.modules,
|
|
"apscheduler.schedulers.asyncio",
|
|
mocks["apscheduler"].schedulers.asyncio,
|
|
)
|
|
monkeypatch.setitem(
|
|
sys.modules,
|
|
"apscheduler.schedulers.background",
|
|
mocks["apscheduler"].schedulers.background,
|
|
)
|
|
yield
|
|
monkeypatch.undo()
|
|
|
|
|
|
class MockTelegramBuilder:
|
|
"""构建 Telegram 测试 mock 对象的工具类。"""
|
|
|
|
@staticmethod
|
|
def create_bot():
|
|
"""创建 mock Telegram bot 实例。"""
|
|
bot = MagicMock()
|
|
bot.username = "test_bot"
|
|
bot.id = 12345678
|
|
bot.base_url = "https://api.telegram.org/bottest_token_123/"
|
|
bot.send_message = AsyncMock()
|
|
bot.send_photo = AsyncMock()
|
|
bot.send_document = AsyncMock()
|
|
bot.send_voice = AsyncMock()
|
|
bot.send_chat_action = AsyncMock()
|
|
bot.delete_my_commands = AsyncMock()
|
|
bot.set_my_commands = AsyncMock()
|
|
bot.set_message_reaction = AsyncMock()
|
|
bot.edit_message_text = AsyncMock()
|
|
bot.send_message_draft = AsyncMock()
|
|
return bot
|
|
|
|
@staticmethod
|
|
def create_application():
|
|
"""创建 mock Telegram Application 实例。"""
|
|
from tests.fixtures.helpers import NoopAwaitable
|
|
|
|
app = MagicMock()
|
|
app.bot = MockTelegramBuilder.create_bot()
|
|
app.initialize = AsyncMock()
|
|
app.start = AsyncMock()
|
|
app.stop = AsyncMock()
|
|
app.shutdown = AsyncMock()
|
|
app.add_handler = MagicMock()
|
|
app.updater = MagicMock()
|
|
app.updater.start_polling = MagicMock(return_value=NoopAwaitable())
|
|
app.updater.stop = AsyncMock()
|
|
app.updater.running = False
|
|
return app
|
|
|
|
@staticmethod
|
|
def create_scheduler():
|
|
"""创建 mock APScheduler 实例。"""
|
|
scheduler = MagicMock()
|
|
scheduler.add_job = MagicMock()
|
|
scheduler.start = MagicMock()
|
|
scheduler.running = True
|
|
scheduler.shutdown = MagicMock()
|
|
return scheduler
|