feat: 完成 NestJS 后端核心底座开发 (M1-M6) 和 Ant Design Vue 前端迁移
主要更新: 1. 后端核心底座完成 (M1-M6): - 健康检查、指标监控、分布式锁 - 事件总线、队列系统、事务管理 - 安全守卫、多租户隔离、存储适配器 - 审计日志、配置管理、多语言支持 2. 前端迁移到 Ant Design Vue: - 从 Element Plus 迁移到 Ant Design Vue - 完善 system 模块 (role/menu/dept) - 修复依赖和配置问题 3. 文档完善: - AI 开发工作流文档 - 架构约束和开发规范 - 项目进度跟踪 4. 其他改进: - 修复编译错误和类型问题 - 完善测试用例 - 优化项目结构
This commit is contained in:
245
wwjcloud/test/database/index-manager.service.spec.ts
Normal file
245
wwjcloud/test/database/index-manager.service.spec.ts
Normal file
@@ -0,0 +1,245 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
import { Repository, DataSource } from 'typeorm';
|
||||
import { IndexManagerService } from '../../src/core/database/index-manager.service';
|
||||
|
||||
/**
|
||||
* IndexManagerService 单元测试
|
||||
* 测试数据库索引管理服务的核心功能
|
||||
*/
|
||||
describe('IndexManagerService', () => {
|
||||
let service: IndexManagerService;
|
||||
let dataSource: DataSource;
|
||||
let mockQueryRunner: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
// 创建模拟的查询运行器
|
||||
mockQueryRunner = {
|
||||
query: jest.fn(),
|
||||
release: jest.fn(),
|
||||
};
|
||||
|
||||
// 创建模拟的数据源
|
||||
const mockDataSource = {
|
||||
createQueryRunner: jest.fn().mockReturnValue(mockQueryRunner),
|
||||
query: jest.fn(),
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
IndexManagerService,
|
||||
{
|
||||
provide: DataSource,
|
||||
useValue: mockDataSource,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<IndexManagerService>(IndexManagerService);
|
||||
dataSource = module.get<DataSource>(DataSource);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('checkIndexExists', () => {
|
||||
it('should return true when index exists', async () => {
|
||||
// 模拟索引存在的查询结果
|
||||
mockQueryRunner.query.mockResolvedValue([{ count: 1 }]);
|
||||
|
||||
const result = await service.checkIndexExists('test_table', 'test_index');
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('SHOW INDEX FROM test_table'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should return false when index does not exist', async () => {
|
||||
// 模拟索引不存在的查询结果
|
||||
mockQueryRunner.query.mockResolvedValue([]);
|
||||
|
||||
const result = await service.checkIndexExists('test_table', 'test_index');
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle database errors gracefully', async () => {
|
||||
// 模拟数据库错误
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Database error'));
|
||||
|
||||
const result = await service.checkIndexExists('test_table', 'test_index');
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createIndex', () => {
|
||||
it('should create single column index successfully', async () => {
|
||||
mockQueryRunner.query.mockResolvedValue(undefined);
|
||||
|
||||
await service.createIndex('test_table', 'test_index', ['column1']);
|
||||
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
'CREATE INDEX test_index ON test_table (column1)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should create composite index successfully', async () => {
|
||||
mockQueryRunner.query.mockResolvedValue(undefined);
|
||||
|
||||
await service.createIndex('test_table', 'test_composite_index', ['column1', 'column2']);
|
||||
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
'CREATE INDEX test_composite_index ON test_table (column1, column2)',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle index creation errors gracefully', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Index creation failed'));
|
||||
|
||||
// 应该不抛出异常,而是记录日志
|
||||
await expect(service.createIndex('test_table', 'test_index', ['column1'])).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getTableIndexes', () => {
|
||||
it('should return table indexes', async () => {
|
||||
const mockIndexes = [
|
||||
{
|
||||
Table: 'test_table',
|
||||
Non_unique: 0,
|
||||
Key_name: 'PRIMARY',
|
||||
Seq_in_index: 1,
|
||||
Column_name: 'id',
|
||||
Collation: 'A',
|
||||
Cardinality: 1000,
|
||||
Sub_part: null,
|
||||
Packed: null,
|
||||
Null: '',
|
||||
Index_type: 'BTREE',
|
||||
Comment: '',
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockIndexes);
|
||||
|
||||
const result = await service.getTableIndexes('test_table');
|
||||
|
||||
expect(result).toEqual(mockIndexes);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
'SHOW INDEX FROM test_table',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when getting table indexes', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.getTableIndexes('test_table');
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('analyzeTable', () => {
|
||||
it('should analyze table successfully', async () => {
|
||||
mockQueryRunner.query.mockResolvedValue(undefined);
|
||||
|
||||
await service.analyzeTable('test_table');
|
||||
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
'ANALYZE TABLE test_table',
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle analyze table errors gracefully', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Analyze failed'));
|
||||
|
||||
await expect(service.analyzeTable('test_table')).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getIndexUsageStats', () => {
|
||||
it('should return index usage statistics', async () => {
|
||||
const mockStats = [
|
||||
{
|
||||
table_schema: 'test_db',
|
||||
table_name: 'test_table',
|
||||
index_name: 'test_index',
|
||||
count_read: 100,
|
||||
sum_timer_read: 1000000,
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockStats);
|
||||
|
||||
const result = await service.getIndexUsageStats();
|
||||
|
||||
expect(result).toEqual(mockStats);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('performance_schema.table_io_waits_summary_by_index_usage'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when getting index usage stats', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.getIndexUsageStats();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkAndCreateIndexes', () => {
|
||||
it('should check and create all required indexes', async () => {
|
||||
// 模拟所有索引都不存在
|
||||
mockQueryRunner.query.mockResolvedValue([]);
|
||||
|
||||
const createIndexSpy = jest.spyOn(service, 'createIndex').mockResolvedValue(undefined);
|
||||
const checkIndexSpy = jest.spyOn(service, 'checkIndexExists').mockResolvedValue(false);
|
||||
|
||||
await service.checkAndCreateIndexes();
|
||||
|
||||
// 验证检查了所有必要的索引
|
||||
expect(checkIndexSpy).toHaveBeenCalledTimes(expect.any(Number));
|
||||
expect(createIndexSpy).toHaveBeenCalledTimes(expect.any(Number));
|
||||
|
||||
createIndexSpy.mockRestore();
|
||||
checkIndexSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should skip creating existing indexes', async () => {
|
||||
const createIndexSpy = jest.spyOn(service, 'createIndex').mockResolvedValue(undefined);
|
||||
const checkIndexSpy = jest.spyOn(service, 'checkIndexExists').mockResolvedValue(true);
|
||||
|
||||
await service.checkAndCreateIndexes();
|
||||
|
||||
// 如果所有索引都存在,则不应该创建任何索引
|
||||
expect(createIndexSpy).not.toHaveBeenCalled();
|
||||
|
||||
createIndexSpy.mockRestore();
|
||||
checkIndexSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe('analyzeHotTables', () => {
|
||||
it('should analyze all hot tables', async () => {
|
||||
const analyzeTableSpy = jest.spyOn(service, 'analyzeTable').mockResolvedValue(undefined);
|
||||
|
||||
await service.analyzeHotTables();
|
||||
|
||||
// 验证分析了所有热点表
|
||||
expect(analyzeTableSpy).toHaveBeenCalledWith('member');
|
||||
expect(analyzeTableSpy).toHaveBeenCalledWith('member_account_log');
|
||||
expect(analyzeTableSpy).toHaveBeenCalledWith('pay');
|
||||
expect(analyzeTableSpy).toHaveBeenCalledWith('pay_refund');
|
||||
|
||||
analyzeTableSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
});
|
||||
335
wwjcloud/test/database/performance-monitor.service.spec.ts
Normal file
335
wwjcloud/test/database/performance-monitor.service.spec.ts
Normal file
@@ -0,0 +1,335 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { DataSource } from 'typeorm';
|
||||
import { PerformanceMonitorService } from '../../src/core/database/performance-monitor.service';
|
||||
|
||||
/**
|
||||
* PerformanceMonitorService 单元测试
|
||||
* 测试数据库性能监控服务的核心功能
|
||||
*/
|
||||
describe('PerformanceMonitorService', () => {
|
||||
let service: PerformanceMonitorService;
|
||||
let dataSource: DataSource;
|
||||
let mockQueryRunner: any;
|
||||
|
||||
beforeEach(async () => {
|
||||
// 创建模拟的查询运行器
|
||||
mockQueryRunner = {
|
||||
query: jest.fn(),
|
||||
release: jest.fn(),
|
||||
};
|
||||
|
||||
// 创建模拟的数据源
|
||||
const mockDataSource = {
|
||||
createQueryRunner: jest.fn().mockReturnValue(mockQueryRunner),
|
||||
query: jest.fn(),
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
PerformanceMonitorService,
|
||||
{
|
||||
provide: DataSource,
|
||||
useValue: mockDataSource,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<PerformanceMonitorService>(PerformanceMonitorService);
|
||||
dataSource = module.get<DataSource>(DataSource);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('checkSlowQueries', () => {
|
||||
it('should return slow queries', async () => {
|
||||
const mockSlowQueries = [
|
||||
{
|
||||
sql_text: 'SELECT * FROM member WHERE status = 1',
|
||||
exec_count: 100,
|
||||
avg_timer_wait: 5000000000, // 5秒
|
||||
sum_timer_wait: 500000000000,
|
||||
sum_rows_examined: 10000,
|
||||
sum_rows_sent: 1000,
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockSlowQueries);
|
||||
|
||||
const result = await service.checkSlowQueries();
|
||||
|
||||
expect(result).toEqual(mockSlowQueries);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('performance_schema.events_statements_summary_by_digest'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when checking slow queries', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.checkSlowQueries();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkTableSizes', () => {
|
||||
it('should return table sizes', async () => {
|
||||
const mockTableSizes = [
|
||||
{
|
||||
table_name: 'member',
|
||||
size_mb: 150.5,
|
||||
rows: 50000,
|
||||
avg_row_length: 3200,
|
||||
data_length: 157286400,
|
||||
index_length: 52428800,
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockTableSizes);
|
||||
|
||||
const result = await service.checkTableSizes();
|
||||
|
||||
expect(result).toEqual(mockTableSizes);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('information_schema.tables'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when checking table sizes', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.checkTableSizes();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkIndexEfficiency', () => {
|
||||
it('should return index efficiency data', async () => {
|
||||
const mockIndexEfficiency = [
|
||||
{
|
||||
table_name: 'member',
|
||||
index_name: 'idx_member_status',
|
||||
cardinality: 5,
|
||||
selectivity: 0.2,
|
||||
usage_count: 1000,
|
||||
efficiency_score: 75.5,
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockIndexEfficiency);
|
||||
|
||||
const result = await service.checkIndexEfficiency();
|
||||
|
||||
expect(result).toEqual(mockIndexEfficiency);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('information_schema.statistics'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when checking index efficiency', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.checkIndexEfficiency();
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getQueryExecutionPlan', () => {
|
||||
it('should return query execution plan', async () => {
|
||||
const mockExecutionPlan = [
|
||||
{
|
||||
id: 1,
|
||||
select_type: 'SIMPLE',
|
||||
table: 'member',
|
||||
partitions: null,
|
||||
type: 'ref',
|
||||
possible_keys: 'idx_member_status',
|
||||
key: 'idx_member_status',
|
||||
key_len: '4',
|
||||
ref: 'const',
|
||||
rows: 1000,
|
||||
filtered: 100.0,
|
||||
Extra: 'Using index condition',
|
||||
},
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockExecutionPlan);
|
||||
|
||||
const sql = 'SELECT * FROM member WHERE status = 1';
|
||||
const result = await service.getQueryExecutionPlan(sql);
|
||||
|
||||
expect(result).toEqual(mockExecutionPlan);
|
||||
expect(mockQueryRunner.query).toHaveBeenCalledWith(`EXPLAIN ${sql}`);
|
||||
});
|
||||
|
||||
it('should handle errors when getting execution plan', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const sql = 'SELECT * FROM member WHERE status = 1';
|
||||
const result = await service.getQueryExecutionPlan(sql);
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('analyzeQueryPerformance', () => {
|
||||
it('should analyze query performance', async () => {
|
||||
const mockExecutionPlan = [
|
||||
{
|
||||
id: 1,
|
||||
select_type: 'SIMPLE',
|
||||
table: 'member',
|
||||
type: 'ref',
|
||||
possible_keys: 'idx_member_status',
|
||||
key: 'idx_member_status',
|
||||
rows: 1000,
|
||||
filtered: 100.0,
|
||||
Extra: 'Using index condition',
|
||||
},
|
||||
];
|
||||
|
||||
jest.spyOn(service, 'getQueryExecutionPlan').mockResolvedValue(mockExecutionPlan);
|
||||
|
||||
const sql = 'SELECT * FROM member WHERE status = 1';
|
||||
const result = await service.analyzeQueryPerformance(sql);
|
||||
|
||||
expect(result).toHaveProperty('executionPlan');
|
||||
expect(result).toHaveProperty('analysis');
|
||||
expect(result).toHaveProperty('recommendations');
|
||||
expect(result.executionPlan).toEqual(mockExecutionPlan);
|
||||
expect(result.analysis.estimatedRows).toBe(1000);
|
||||
expect(result.analysis.usesIndex).toBe(true);
|
||||
});
|
||||
|
||||
it('should detect full table scan', async () => {
|
||||
const mockExecutionPlan = [
|
||||
{
|
||||
id: 1,
|
||||
select_type: 'SIMPLE',
|
||||
table: 'member',
|
||||
type: 'ALL',
|
||||
possible_keys: null,
|
||||
key: null,
|
||||
rows: 50000,
|
||||
filtered: 10.0,
|
||||
Extra: 'Using where',
|
||||
},
|
||||
];
|
||||
|
||||
jest.spyOn(service, 'getQueryExecutionPlan').mockResolvedValue(mockExecutionPlan);
|
||||
|
||||
const sql = 'SELECT * FROM member WHERE name LIKE "%test%"';
|
||||
const result = await service.analyzeQueryPerformance(sql);
|
||||
|
||||
expect(result.analysis.hasFullTableScan).toBe(true);
|
||||
expect(result.analysis.usesIndex).toBe(false);
|
||||
expect(result.recommendations).toContain('查询执行了全表扫描,建议添加适当的索引');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConnectionStatus', () => {
|
||||
it('should return connection status', async () => {
|
||||
const mockConnectionStatus = [
|
||||
{ Variable_name: 'Threads_connected', Value: '25' },
|
||||
{ Variable_name: 'Max_connections', Value: '151' },
|
||||
{ Variable_name: 'Threads_running', Value: '5' },
|
||||
{ Variable_name: 'Aborted_connects', Value: '10' },
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockConnectionStatus);
|
||||
|
||||
const result = await service.getConnectionStatus();
|
||||
|
||||
expect(result).toHaveProperty('threadsConnected');
|
||||
expect(result).toHaveProperty('maxConnections');
|
||||
expect(result).toHaveProperty('connectionUsage');
|
||||
expect(result.threadsConnected).toBe(25);
|
||||
expect(result.maxConnections).toBe(151);
|
||||
expect(result.connectionUsage).toBeCloseTo(16.56, 1);
|
||||
});
|
||||
|
||||
it('should handle errors when getting connection status', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.getConnectionStatus();
|
||||
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPerformanceMetrics', () => {
|
||||
it('should return performance metrics', async () => {
|
||||
const mockMetrics = [
|
||||
{ Variable_name: 'Innodb_buffer_pool_read_requests', Value: '1000000' },
|
||||
{ Variable_name: 'Innodb_buffer_pool_reads', Value: '50000' },
|
||||
{ Variable_name: 'Slow_queries', Value: '100' },
|
||||
{ Variable_name: 'Questions', Value: '500000' },
|
||||
{ Variable_name: 'Uptime', Value: '86400' },
|
||||
{ Variable_name: 'Threads_created', Value: '200' },
|
||||
{ Variable_name: 'Connections', Value: '10000' },
|
||||
];
|
||||
|
||||
mockQueryRunner.query.mockResolvedValue(mockMetrics);
|
||||
|
||||
const result = await service.getPerformanceMetrics();
|
||||
|
||||
expect(result).toHaveProperty('buffer_pool_hit_rate');
|
||||
expect(result).toHaveProperty('slow_query_rate');
|
||||
expect(result).toHaveProperty('qps');
|
||||
expect(result).toHaveProperty('thread_cache_hit_rate');
|
||||
expect(result.buffer_pool_hit_rate).toBeCloseTo(95, 0);
|
||||
expect(result.slow_query_rate).toBeCloseTo(0.02, 2);
|
||||
});
|
||||
|
||||
it('should handle errors when getting performance metrics', async () => {
|
||||
mockQueryRunner.query.mockRejectedValue(new Error('Query failed'));
|
||||
|
||||
const result = await service.getPerformanceMetrics();
|
||||
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe('performanceCheck', () => {
|
||||
it('should perform complete performance check', async () => {
|
||||
const checkSlowQueriesSpy = jest.spyOn(service, 'checkSlowQueries').mockResolvedValue([]);
|
||||
const checkTableSizesSpy = jest.spyOn(service, 'checkTableSizes').mockResolvedValue([]);
|
||||
const checkIndexEfficiencySpy = jest.spyOn(service, 'checkIndexEfficiency').mockResolvedValue([]);
|
||||
const getConnectionStatusSpy = jest.spyOn(service, 'getConnectionStatus').mockResolvedValue({});
|
||||
const getPerformanceMetricsSpy = jest.spyOn(service, 'getPerformanceMetrics').mockResolvedValue({});
|
||||
|
||||
await service.performanceCheck();
|
||||
|
||||
expect(checkSlowQueriesSpy).toHaveBeenCalled();
|
||||
expect(checkTableSizesSpy).toHaveBeenCalled();
|
||||
expect(checkIndexEfficiencySpy).toHaveBeenCalled();
|
||||
expect(getConnectionStatusSpy).toHaveBeenCalled();
|
||||
expect(getPerformanceMetricsSpy).toHaveBeenCalled();
|
||||
|
||||
checkSlowQueriesSpy.mockRestore();
|
||||
checkTableSizesSpy.mockRestore();
|
||||
checkIndexEfficiencySpy.mockRestore();
|
||||
getConnectionStatusSpy.mockRestore();
|
||||
getPerformanceMetricsSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle errors during performance check', async () => {
|
||||
jest.spyOn(service, 'checkSlowQueries').mockRejectedValue(new Error('Check failed'));
|
||||
jest.spyOn(service, 'checkTableSizes').mockResolvedValue([]);
|
||||
jest.spyOn(service, 'checkIndexEfficiency').mockResolvedValue([]);
|
||||
jest.spyOn(service, 'getConnectionStatus').mockResolvedValue({});
|
||||
jest.spyOn(service, 'getPerformanceMetrics').mockResolvedValue({});
|
||||
|
||||
// 应该不抛出异常
|
||||
await expect(service.performanceCheck()).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user