/**
* Jest 测试环境设置文件
* 在所有测试运行前执行
*/
// 设置测试环境变量
process.env.NODE_ENV = 'test';
process.env.ZENDTAO_BASE_URL = 'http://localhost:3000';
process.env.ZENDTAO_TOKEN = 'test-token-for-testing';
// 设置默认超时
jest.setTimeout(30000);
// 全局测试工具函数
declare global {
namespace jest {
interface Matchers<R> {
toBeValidMcpResponse(): R;
toHaveValidToolStructure(): R;
}
}
}
// 自定义匹配器
expect.extend({
toBeValidMcpResponse(received: any) {
const pass = received &&
typeof received === 'object' &&
received.content &&
Array.isArray(received.content);
if (pass) {
return {
message: () => `expected ${received} not to be a valid MCP response`,
pass: true,
};
} else {
return {
message: () => `expected ${received} to be a valid MCP response with content array`,
pass: false,
};
}
},
toHaveValidToolStructure(received: any) {
const pass = received &&
typeof received === 'object' &&
received.name &&
typeof received.name === 'string' &&
received.description &&
typeof received.description === 'string';
if (pass) {
return {
message: () => `expected ${received} not to have valid tool structure`,
pass: true,
};
} else {
return {
message: () => `expected ${received} to have valid tool structure with name and description`,
pass: false,
};
}
}
});
// Mock console 方法以减少测试输出噪音
const originalConsole = { ...console };
beforeEach(() => {
// 可以选择性 mock console 方法
// console.log = jest.fn();
// console.info = jest.fn();
// console.warn = jest.fn();
// console.error = jest.fn();
});
afterEach(() => {
// 恢复 console 方法
// Object.assign(console, originalConsole);
// 清理所有 mock
jest.clearAllMocks();
});
// 全局错误处理
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
});
// 导出测试工具函数
export const testUtils = {
/**
* 创建模拟的项目数据
*/
createMockProject: (overrides = {}) => ({
id: 1,
name: 'Test Project',
code: 'TP001',
status: 'active',
begin: '2024-01-01',
end: '2024-12-31',
acl: 'open',
...overrides
}),
/**
* 创建模拟的任务数据
*/
createMockTask: (overrides = {}) => ({
id: 1,
name: 'Test Task',
project: 1,
status: 'wait',
pri: 1,
estimate: 8,
assignedTo: null,
deadline: null,
...overrides
}),
/**
* 创建模拟的 API 响应
*/
createMockApiResponse: (data: any, status = 200) => ({
status,
data,
message: status === 200 ? 'Success' : 'Error'
}),
/**
* 等待指定时间
*/
wait: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
/**
* 创建模拟的 ZenTao 错误
*/
createMockZenTaoError: (message: string, code = 500) => {
const error = new Error(message) as any;
error.code = code;
error.status = code;
return error;
}
};
// 导出类型定义
export type MockProject = ReturnType<typeof testUtils.createMockProject>;
export type MockTask = ReturnType<typeof testUtils.createMockTask>;
export type MockApiResponse = ReturnType<typeof testUtils.createMockApiResponse>;