- 重构sys模块架构,严格按admin/api/core分层 - 对齐所有sys实体与数据库表结构 - 实现完整的adminapi控制器,匹配PHP/Java契约 - 修复依赖注入问题,确保服务正确注册 - 添加自动迁移工具和契约验证 - 完善多租户支持和审计功能 - 统一命名规范,与PHP业务逻辑保持一致
71 lines
2.6 KiB
TypeScript
71 lines
2.6 KiB
TypeScript
import { Test, TestingModule } from '@nestjs/testing';
|
||
import { INestApplication } from '@nestjs/common';
|
||
import request from 'supertest';
|
||
import { HealthzController } from '../src/core/health/healthzController';
|
||
import { HealthService } from '../src/core/health/healthService';
|
||
|
||
// 使用最小化测试应用,避免引入 AppModule 的外部依赖(DB/Redis/Kafka 等)
|
||
describe('Health Endpoints (e2e)', () => {
|
||
let app: INestApplication;
|
||
|
||
beforeAll(async () => {
|
||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||
controllers: [HealthzController],
|
||
providers: [
|
||
{
|
||
provide: HealthService,
|
||
useValue: {
|
||
// 模拟健康检查,保证端点可用
|
||
check: jest.fn(async () => ({ status: 'ok' })),
|
||
detailedCheck: jest.fn(async () => [
|
||
{ name: 'database', status: 'up' },
|
||
{ name: 'queue', status: 'up' },
|
||
{ name: 'eventBus', status: 'up' },
|
||
{ name: 'cache', status: 'up' },
|
||
]),
|
||
checkDatabase: jest.fn(async () => ({ status: 'up' })),
|
||
},
|
||
},
|
||
],
|
||
}).compile();
|
||
|
||
app = moduleFixture.createNestApplication();
|
||
await app.init();
|
||
});
|
||
|
||
afterAll(async () => {
|
||
if (app) await app.close();
|
||
});
|
||
|
||
it('GET /healthz should be public and return 200 or 503 with JSON body', async () => {
|
||
const res = await request(app.getHttpServer()).get('/healthz');
|
||
expect([200, 503]).toContain(res.status);
|
||
expect(res.headers['content-type']).toMatch(/json/);
|
||
expect(res.body).toHaveProperty('status');
|
||
});
|
||
|
||
it('GET /readyz should be public and return 200 or 503 with JSON body', async () => {
|
||
const res = await request(app.getHttpServer()).get('/readyz');
|
||
expect([200, 503]).toContain(res.status);
|
||
expect(res.headers['content-type']).toMatch(/json/);
|
||
expect(res.body).toHaveProperty('status');
|
||
});
|
||
|
||
it('GET /health/livez alias should respond', async () => {
|
||
const res = await request(app.getHttpServer()).get('/health/livez');
|
||
expect([200, 503]).toContain(res.status);
|
||
});
|
||
|
||
it('GET /health/readyz alias should respond', async () => {
|
||
const res = await request(app.getHttpServer()).get('/health/readyz');
|
||
expect([200, 503]).toContain(res.status);
|
||
});
|
||
|
||
it('GET /startupz should be public and return 200 or 503 with JSON body', async () => {
|
||
const res = await request(app.getHttpServer()).get('/startupz');
|
||
expect([200, 503]).toContain(res.status);
|
||
expect(res.headers['content-type']).toMatch(/json/);
|
||
expect(res.body).toHaveProperty('status');
|
||
});
|
||
});
|