Testing - Coverage & Quick Reference
Coverage Reports
Section titled βCoverage ReportsβGenerate Coverage
Section titled βGenerate Coverageβ# Generate coverage reportnpm run test:cov
# View coverage in browseropen coverage/lcov-report/index.htmlCoverage Goals
Section titled βCoverage Goalsβ- Statements: > 80%
- Branches: > 75%
- Functions: > 80%
- Lines: > 80%
What to Exclude from Coverage
Section titled βWhat to Exclude from CoverageβcollectCoverageFrom: [ 'src/**/*.(t|j)s', '!src/main.ts', // Bootstrap file '!src/**/*.module.ts', // Module definitions '!src/**/*.dto.ts', // Data transfer objects '!src/**/*.entity.ts', // Database entities '!src/**/*.enum.ts', // Enums '!src/**/*.interface.ts', // Type definitions],Summary Checklist
Section titled βSummary ChecklistβBefore submitting tests, verify:
Unit Tests:
- Mock service layer using factory from
test/mocks/ - Test all controller methods (create, update, findOne, findAll, delete)
- Test both success and error cases
- Verify service methods are called with correct arguments
- Clear mocks in
afterEach
E2E Tests:
- Test full HTTP request/response pipeline
- Verify routing works correctly
- Test ValidationPipe (400 for invalid DTOs)
- Test TransformInterceptor (JSON:API response format)
- Test AllExceptionsFilter (error responses)
- Verify
response.bodystructure matches JSON:API spec - Close app in
afterAll
General:
- Tests follow AAA pattern (Arrange, Act, Assert)
- Test names are descriptive
- Each test focuses on one thing
- Coverage meets minimum thresholds (>80%)
- All tests pass locally before pushing
Quick Reference
Section titled βQuick ReferenceβSupertest Request Methods
Section titled βSupertest Request Methodsβ// GET requestawait request(server).get('/engagements/123/orders').expect(200);
// POST request with bodyawait request(server).post('/engagements/123/orders').send(createDTO).expect(201);
// PATCH requestawait request(server).patch('/engagements/123/orders/456').send(updateDTO).expect(200);
// DELETE requestawait request(server).delete('/engagements/123/orders/456').expect(204);
// With query parametersawait request(server).get('/engagements/123/orders').query({ page: 1, limit: 10 }).expect(200);
// Check response bodyconst response = await request(server).get('/engagements/123/orders/456').expect(200);expect(response.body.data.id).toBe('456');Common Mock Patterns
Section titled βCommon Mock Patternsβ// Mock successful responsemockService.findOne.mockResolvedValue(mockEntity);
// Mock errormockService.findOne.mockRejectedValue(new NotFoundException());
// Mock different return values for multiple callsmockService.findOne .mockResolvedValueOnce({ id: '1' }) .mockResolvedValueOnce({ id: '2' }) .mockResolvedValueOnce({ id: '3' });
// Mock with custom logicmockService.findOne.mockImplementation(async (id: string) => { if (id === 'valid-id') { return { id, name: 'Test' }; } throw new NotFoundException();});JSON:API Response Assertions
Section titled βJSON:API Response Assertionsβ// Single resourceexpect(response.body).toEqual( expect.objectContaining({ data: expect.objectContaining({ type: 'engagement-orders', id: expect.any(String), attributes: expect.objectContaining({ order_type: 'LAB', }), }), status: expect.objectContaining({ code: 200000 }), links: expect.objectContaining({ self: expect.any(String) }), }),);
// Paginated collectionexpect(response.body).toEqual( expect.objectContaining({ data: expect.any(Array), meta: expect.objectContaining({ pagination: expect.objectContaining({ page: 1, page_size: 10, total: expect.any(Number), total_pages: expect.any(Number), }), }), links: expect.objectContaining({ self: expect.any(String), first: expect.any(String), last: expect.any(String), }), }),);File Structure Reference
Section titled βFile Structure ReferenceβStandard locations for test artifacts within a bounded context:
apps/[service-name]/βββ jest.config.js # Unit test Jest configurationβββ test/β βββ jest-e2e.json # E2E test Jest configurationβ βββ mocks/β β βββ mock-[entity-name].ts # Mock factory (service + entity + DTO)β βββ unit/β β βββ [entity-name].controller.spec.ts # Controller unit testsβ β βββ [entity-name].service.spec.ts # Service unit testsβ βββ e2e/β βββ [entity-name].e2e-spec.ts # E2E testsβββ ...libs/βββ common/ βββ src/ βββ testing/ βββ test-setup.ts # createTestApp + createTestingModule helpers