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');
|
|||
|
|
});
|
|||
|
|
});
|