Testing
The engine uses Jest for both unit and end-to-end testing. Unit tests live alongside source files; E2E tests live in the test/ directory.
Unit Tests
npm run test # run all unit tests
npm run test:watch # watch mode
npm run test:cov # with coverage report
Unit tests are colocated with the source files they test (e.g., my-service.spec.ts next to my-service.ts).
Mocking Dependencies
Use NestJS's Test.createTestingModule with useValue for clean dependency injection:
describe('MyService', () => {
let service: MyService
let mockDep: jest.Mocked<DependencyService>
beforeEach(async () => {
mockDep = {
doWork: jest.fn().mockResolvedValue(result),
} as unknown as jest.Mocked<DependencyService>
const module = await Test.createTestingModule({
providers: [
MyService,
{ provide: DependencyService, useValue: mockDep },
],
}).compile()
service = module.get<MyService>(MyService)
})
})
Testing Event Subscribers
DB subscribers are the bridge between the ORM and the event system. Test that they:
- Can be instantiated
- Subscribe to the correct entities
- Handle events correctly
describe('WorkflowDefinitionSubscriberService', () => {
let service: WorkflowDefinitionSubscriberService
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [WorkflowDefinitionSubscriberService],
}).compile()
service = module.get(WorkflowDefinitionSubscriberService)
})
it('should subscribe to Workflow entities', () => {
expect(service.getSubscribedEntities()).toContain(Workflow)
})
})
End-to-End Tests
Database Setup
Each E2E test gets a fresh PostgreSQL database. The setup:
- Creates a new database with a unique name
- Runs all migrations
- Swaps
CmsClientModuleforCmsClientMockModule(no real CMS needed) - On test success: drops the database
- On test failure: retains the database for debugging
import { initNestApplication } from '../setup/init-nest-application'
describe('MyController (e2e)', () => {
let app: INestApplication
beforeAll(async () => {
app = await initNestApplication()
})
afterAll(async () => {
await initNestApplication.teardown(app)
})
})
Debugging E2E Tests
To find the test database name, look for the [TESTDB] tag in test output:
Connect to this database directly to inspect state after a failed test.
Playbook Pattern
The most powerful E2E testing approach is the Playbook pattern, described in detail in E2E Playbooks. It lets you define complete workflow execution scenarios declaratively.