feat: 添加测试覆盖率并修复相关问题

refactor(redis_manager): 移除冗余的ConnectionError处理
refactor(event_handler): 优化Bot类型注解
refactor(factory): 移除未使用的GroupCardNoticeEvent

test: 添加全面的单元测试覆盖
- 添加test_import.py测试模块导入
- 添加test_debug.py测试插件加载调试
- 添加test_plugin_error.py测试错误处理
- 添加test_config_loader.py测试配置加载
- 添加test_redis_manager.py测试Redis管理
- 添加test_bot.py测试Bot功能
- 扩展test_models.py测试消息模型
- 添加test_plugin_manager_coverage.py测试插件管理
- 添加test_executor.py测试代码执行器
- 添加test_ws.py测试WebSocket
- 添加test_api.py测试API接口
- 添加test_core_managers.py测试核心管理模块

fix(plugin_manager): 修复插件加载日志变量问题

覆盖率已到达86%(忽略插件)
This commit is contained in:
2026-01-09 23:18:58 +08:00
parent ec3a1c8eac
commit 8508fc95f5
17 changed files with 2057 additions and 112 deletions

179
tests/test_ws.py Normal file
View File

@@ -0,0 +1,179 @@
import pytest
import asyncio
from unittest.mock import MagicMock, AsyncMock, patch
from core.ws import WS
from core.bot import Bot
from models.objects import GroupInfo, StrangerInfo
class TestWS:
@pytest.mark.asyncio
async def test_ws_initialization(self):
"""测试 WS 类初始化。"""
# 模拟全局配置
with patch('core.ws.global_config') as mock_config:
mock_config.napcat_ws.uri = "ws://localhost:8080"
mock_config.napcat_ws.token = "test_token"
mock_config.napcat_ws.reconnect_interval = 5
ws = WS()
assert ws.url == "ws://localhost:8080"
assert ws.token == "test_token"
assert ws.reconnect_interval == 5
assert ws.ws is None
assert ws.bot is None
assert ws.self_id is None
assert ws.code_executor is None
@pytest.mark.asyncio
async def test_call_api(self):
"""测试调用 API 方法。"""
with patch('core.ws.global_config') as mock_config:
mock_config.napcat_ws.uri = "ws://localhost:8080"
mock_config.napcat_ws.token = "test_token"
mock_config.napcat_ws.reconnect_interval = 5
ws = WS()
# 测试 WebSocket 未初始化的情况
result = await ws.call_api("send_group_msg", {"group_id": 123456, "message": "test"})
assert result == {"status": "failed", "msg": "websocket not initialized"}
# 测试 WebSocket 已初始化但未连接的情况
mock_ws = MagicMock()
mock_ws.state = None
ws.ws = mock_ws
result = await ws.call_api("send_group_msg", {"group_id": 123456, "message": "test"})
assert result == {"status": "failed", "msg": "websocket is not open"}
@pytest.mark.asyncio
async def test_on_event_bot_initialization(self):
"""测试事件处理中的 Bot 初始化。"""
with patch('core.ws.global_config') as mock_config:
mock_config.napcat_ws.uri = "ws://localhost:8080"
mock_config.napcat_ws.token = "test_token"
mock_config.napcat_ws.reconnect_interval = 5
ws = WS()
# 模拟包含 self_id 的事件
event_data = {
"post_type": "message",
"message_type": "private",
"self_id": 123456,
"user_id": 789012,
"message": "test",
"raw_message": "test"
}
# 模拟事件工厂
with patch('core.ws.EventFactory') as mock_factory:
mock_event = MagicMock()
mock_event.post_type = "message"
mock_event.self_id = 123456
mock_event.sender = None
mock_event.message_type = "private"
mock_event.user_id = 789012
mock_event.raw_message = "test"
mock_factory.create_event.return_value = mock_event
# 模拟命令管理器
with patch('core.ws.matcher') as mock_matcher:
mock_matcher.handle_event = AsyncMock()
await ws.on_event(event_data)
# 验证 Bot 已初始化
assert ws.bot is not None
assert isinstance(ws.bot, Bot)
assert ws.self_id == 123456
# 验证事件处理
mock_factory.create_event.assert_called_once_with(event_data)
mock_matcher.handle_event.assert_called_once()
@pytest.mark.asyncio
async def test_on_event_no_bot(self):
"""测试 Bot 未初始化时的事件处理。"""
with patch('core.ws.global_config') as mock_config:
mock_config.napcat_ws.uri = "ws://localhost:8080"
mock_config.napcat_ws.token = "test_token"
mock_config.napcat_ws.reconnect_interval = 5
ws = WS()
# 模拟不包含 self_id 的事件
event_data = {
"post_type": "message",
"message_type": "private",
"user_id": 789012,
"message": "test",
"raw_message": "test"
}
# 模拟事件工厂
with patch('core.ws.EventFactory') as mock_factory:
mock_event = MagicMock()
mock_event.post_type = "message"
# 确保事件没有 self_id 属性
del mock_event.self_id
mock_event.sender = None
mock_event.message_type = "private"
mock_event.user_id = 789012
mock_event.raw_message = "test"
mock_factory.create_event.return_value = mock_event
# 模拟命令管理器
with patch('core.ws.matcher') as mock_matcher:
mock_matcher.handle_event = AsyncMock()
await ws.on_event(event_data)
# 验证 Bot 未初始化
assert ws.bot is None
assert ws.self_id is None
# 验证事件处理未被调用
mock_matcher.handle_event.assert_not_called()
@pytest.mark.asyncio
async def test_call_api_with_code_executor(self):
"""测试带代码执行器的 WS 初始化。"""
with patch('core.ws.global_config') as mock_config:
mock_config.napcat_ws.uri = "ws://localhost:8080"
mock_config.napcat_ws.token = "test_token"
mock_config.napcat_ws.reconnect_interval = 5
mock_executor = MagicMock()
ws = WS(code_executor=mock_executor)
# 模拟包含 self_id 的事件
event_data = {
"post_type": "message",
"message_type": "private",
"self_id": 123456,
"user_id": 789012,
"message": "test",
"raw_message": "test"
}
# 模拟事件工厂
with patch('core.ws.EventFactory') as mock_factory:
mock_event = MagicMock()
mock_event.post_type = "message"
mock_event.self_id = 123456
mock_event.sender = None
mock_event.message_type = "private"
mock_event.user_id = 789012
mock_event.raw_message = "test"
mock_factory.create_event.return_value = mock_event
# 模拟命令管理器
with patch('core.ws.matcher') as mock_matcher:
mock_matcher.handle_event = AsyncMock()
await ws.on_event(event_data)
# 验证代码执行器已注入
assert ws.bot.code_executor is mock_executor
assert mock_executor.bot is ws.bot