Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/About test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
1. 单元测试位于/test
2. 执行特定测试的具体例子:
npx vitest test/controllers/aiChatController.test.ts
54 changes: 54 additions & 0 deletions test/controllers/aiChatController.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { AiChatController } from "../../src/controllers/aiChatController";
import { modelConfigManager } from "../../src/llm/utils/modelConfigManager";

// Mock modelConfigManager
vi.mock("../../src/llm/utils/modelConfigManager", () => {
const mockModelConfigManager = {
getNonEmbeddingModels: vi.fn(),
getDefaultModel: vi.fn(),
};

return {
modelConfigManager: mockModelConfigManager,
};
});

describe("AiChatController", () => {
let controller: AiChatController;

beforeEach(() => {
controller = new AiChatController();
});

afterEach(() => {
vi.clearAllMocks();
});

describe("getAvailableModels", () => {
it("should return available models successfully", async () => {
// Arrange: 设置模拟数据
const mockModels = [
{ id: "1", name: "gpt-4", displayName: "GPT-4" },
{ id: "2", name: "claude-2", displayName: "Claude 2" },
];

const mockDefaultModel = {
id: "1",
name: "gpt-4",
displayName: "GPT-4"
};

(modelConfigManager.getNonEmbeddingModels as vi.Mock).mockReturnValue(mockModels);
(modelConfigManager.getDefaultModel as vi.Mock).mockReturnValue(mockDefaultModel);

// Act: 调用方法
const result = await controller.getAvailableModels();

// Assert: 验证结果
expect(result.success).toBe(true);
expect(result.data.all).toHaveLength(2);
expect(result.data.default).toBe("GPT-4");
});
});
});
66 changes: 66 additions & 0 deletions test/llm/modelConfigManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import * as fs from 'fs';
import * as path from 'path';
import { ModelConfigManager } from '../../src/llm/utils/modelConfigManager';

describe('ModelConfigManager', () => {
/*
TODO 这并不是很好的读取配置的办法,因为Manager固定读取指定位置的Config
所以无法注入我们的测试Config,所以只能在指定位置写入一个文件。
这可能导致运行测试时错误的覆盖正确的配置文件。
*/
const testConfigPath = path.join(process.cwd(), '/src/config/llm-config.json');

beforeEach(() => {
// 创建一个临时的测试配置文件
const testConfig = {
models: [
{
id: 'test-model-1',
name: 'Test Model 1',
provider: 'openai',
baseUrl: 'https://api.openai.com',
apiKey: 'test-key-1',
displayName: 'Test Model 1 Display'
},
{
id: 'test-model-2',
name: 'Test Model 2',
provider: 'anthropic',
baseUrl: 'https://api.anthropic.com',
apiKey: 'test-key-2',
displayName: 'Test Model 2 Display',
isEmbeddingModel: true
}
]
};

// 将测试配置写入临时文件
fs.writeFileSync(testConfigPath, JSON.stringify(testConfig, null, 2));
});

afterEach(() => {
// 清理临时文件
if (fs.existsSync(testConfigPath)) {
fs.unlinkSync(testConfigPath);
}
});

it('should load configs correctly from file', () => {
// 通过修改环境或使用技巧让ModelConfigManager加载我们的测试配置
// 这里我们直接测试loadConfigs方法的逻辑

// 创建一个ModelConfigManager实例
const manager = new ModelConfigManager();

// 验证manager已正确初始化
expect(manager).toBeDefined();

// 获取所有模型
const allModels = manager.getAllModels();
console.log("All models:", allModels);
expect(allModels).toBeDefined();
expect(Array.isArray(allModels)).toBe(true);

});
});