Skip to main content
Glama
mcp-server.test.ts8.65 kB
import { HeroSummonerServer } from '../../src/server'; import { Persona } from '../../src/types'; import * as fs from 'fs'; import * as path from 'path'; // 加载测试数据 const testPersonasPath = path.join(__dirname, '../fixtures/test-personas.json'); const testPersonas: Persona[] = JSON.parse(fs.readFileSync(testPersonasPath, 'utf-8')); // Mock fetch global.fetch = jest.fn(); describe('MCP服务器集成测试', () => { let server: HeroSummonerServer; let mockFetch: jest.MockedFunction<typeof fetch>; beforeEach(() => { mockFetch = global.fetch as jest.MockedFunction<typeof fetch>; mockFetch.mockClear(); // 使用测试人格初始化服务器 const localPersonas = testPersonas.filter(p => p.source === 'local'); server = new HeroSummonerServer(localPersonas); }); afterEach(() => { jest.clearAllMocks(); }); describe('服务器初始化', () => { test('应该正确初始化服务器', () => { expect(server).toBeInstanceOf(HeroSummonerServer); }); test('应该接受空的本地人格列表', () => { const emptyServer = new HeroSummonerServer([]); expect(emptyServer).toBeInstanceOf(HeroSummonerServer); }); }); describe('工具列表', () => { test('应该返回所有可用工具', async () => { const tools = await server.getAvailableTools(); expect(tools).toContain('summon_persona'); expect(tools).toContain('list_personas'); expect(tools).toContain('search_personas'); expect(tools).toContain('start_collaboration'); expect(tools).toContain('get_tool_stats'); }); }); describe('人格召唤工具', () => { test('应该成功召唤存在的人格', async () => { const result = await server.callTool('summon_persona', { persona_name: '测试暴躁老哥' }); expect(result.content).toHaveLength(1); expect(result.content[0].type).toBe('text'); expect(result.content[0].text).toContain('测试暴躁老哥'); expect(result.content[0].text).toContain('已召唤'); }); test('应该处理不存在的人格', async () => { const result = await server.callTool('summon_persona', { persona_name: '不存在的人格' }); expect(result.content[0].text).toContain('找不到人格'); expect(result.content[0].text).toContain('可用人格'); }); test('应该处理空参数', async () => { const result = await server.callTool('summon_persona', {}); expect(result.content[0].text).toContain('❌'); }); }); describe('人格列表工具', () => { test('应该返回所有人格列表', async () => { const result = await server.callTool('list_personas', {}); expect(result.content[0].text).toContain('可用人格'); expect(result.content[0].text).toContain('测试暴躁老哥'); expect(result.content[0].text).toContain('测试自省姐'); }); test('应该支持按分类筛选', async () => { const result = await server.callTool('list_personas', { category: 'analysis' }); expect(result.content[0].text).toContain('analysis'); }); test('应该支持按来源筛选', async () => { const result = await server.callTool('list_personas', { source: 'local' }); expect(result.content[0].text).toContain('本地人格'); }); }); describe('人格搜索工具', () => { test('应该成功搜索人格', async () => { const result = await server.callTool('search_personas', { query: '暴躁' }); expect(result.content[0].text).toContain('搜索结果'); expect(result.content[0].text).toContain('测试暴躁老哥'); }); test('应该处理无结果搜索', async () => { const result = await server.callTool('search_personas', { query: '不存在的关键词xyz123' }); expect(result.content[0].text).toContain('未找到匹配'); }); test('应该拒绝过短的查询', async () => { const result = await server.callTool('search_personas', { query: 'ab' }); expect(result.content[0].text).toContain('❌'); }); }); describe('协作分析工具', () => { test('应该处理没有配置的情况', async () => { const result = await server.callTool('start_collaboration', { query: '分析这个商业模式' }); expect(result.content[0].text).toContain('未找到活跃配置'); }); test('应该验证查询参数', async () => { const result = await server.callTool('start_collaboration', { query: 'abc' // 过短 }); expect(result.content[0].text).toContain('❌'); }); }); describe('统计工具', () => { test('应该返回工具使用统计', async () => { // 先调用几个工具 await server.callTool('summon_persona', { persona_name: '测试暴躁老哥' }); await server.callTool('list_personas', {}); const result = await server.callTool('get_tool_stats', {}); expect(result.content[0].text).toContain('工具使用统计'); expect(result.content[0].text).toContain('总调用次数'); }); test('应该支持查询单个工具统计', async () => { await server.callTool('summon_persona', { persona_name: '测试暴躁老哥' }); const result = await server.callTool('get_tool_stats', { toolName: 'summon_persona' }); expect(result.content[0].text).toContain('summon_persona'); expect(result.content[0].text).toContain('调用次数'); }); }); describe('错误处理', () => { test('应该处理未知工具', async () => { await expect(server.callTool('unknown_tool', {})).rejects.toThrow(); }); test('应该处理网络错误', async () => { mockFetch.mockRejectedValue(new Error('Network error')); // 这应该不会导致服务器崩溃,而是使用本地人格 const result = await server.callTool('list_personas', {}); expect(result.content[0].text).toContain('可用人格'); }); test('应该处理无效的JSON参数', async () => { const result = await server.callTool('summon_persona', 'invalid json' as any); expect(result.content[0].text).toContain('❌'); }); }); describe('性能测试', () => { test('应该在合理时间内响应', async () => { const startTime = Date.now(); await server.callTool('list_personas', {}); const endTime = Date.now(); const duration = endTime - startTime; // 应该在1秒内完成 expect(duration).toBeLessThan(1000); }); test('应该支持并发调用', async () => { const promises = [ server.callTool('list_personas', {}), server.callTool('search_personas', { query: '测试' }), server.callTool('summon_persona', { persona_name: '测试暴躁老哥' }) ]; const results = await Promise.all(promises); // 所有调用都应该成功 results.forEach(result => { expect(result.content).toHaveLength(1); expect(result.content[0].type).toBe('text'); }); }); }); describe('状态管理', () => { test('应该正确维护工具调用统计', async () => { // 调用多个工具 await server.callTool('summon_persona', { persona_name: '测试暴躁老哥' }); await server.callTool('list_personas', {}); await server.callTool('search_personas', { query: '测试' }); const statsResult = await server.callTool('get_tool_stats', {}); expect(statsResult.content[0].text).toContain('总调用次数: 4'); // 包括get_tool_stats本身 }); test('应该正确处理人格仓库更新', async () => { // 初始状态 const initialResult = await server.callTool('list_personas', {}); const initialCount = (initialResult.content[0].text.match(/\d+/g) || []).map(Number)[0]; // 模拟添加新人格(通过配置更新) const newPersona: Persona = { id: 'new_test_persona', name: '新测试人格', rule: '新测试规则', goal: '新测试目标', version: '1.0.0', source: 'local' }; await server.updatePersonaRepository([newPersona]); const updatedResult = await server.callTool('list_personas', {}); expect(updatedResult.content[0].text).toContain('新测试人格'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/juyitingmcp/juyitingmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server