diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index 5a5f65a5a9..c3e2a3fa3d 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -170,7 +170,7 @@ export class BackendInitializer { async stop(): Promise { if (!this.#started) { - throw new Error('Backend has not started'); + return; } this.#started = false; diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index 3df3f3cb21..90a315f745 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -31,6 +31,8 @@ export interface TestBackendOptions< TServices extends any[], TExtensionPoints extends any[], > { + // (undocumented) + autoStop?: boolean; // (undocumented) extensionPoints?: readonly [ ...{ diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts index b87e157477..383a182db2 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -32,7 +32,7 @@ describe('TestBackend', () => { const extensionPoint3 = createExtensionPoint({ id: 'b3' }); const extensionPoint4 = createExtensionPoint({ id: 'b4' }); const extensionPoint5 = createExtensionPoint({ id: 'b5' }); - const backend = await startTestBackend({ + await startTestBackend({ services: [ // @ts-expect-error [extensionPoint1, { a: 'a' }], @@ -59,7 +59,6 @@ describe('TestBackend', () => { ], }); expect(1).toBe(1); - await backend.stop(); }); it('should start the test backend', async () => { @@ -89,13 +88,12 @@ describe('TestBackend', () => { }, }); - const backend = await startTestBackend({ + await startTestBackend({ services: [sf], features: [testModule()], }); expect(testFn).toHaveBeenCalledWith('winning'); - await backend.stop(); }); it('should stop the test backend', async () => { @@ -119,6 +117,7 @@ describe('TestBackend', () => { const backend = await startTestBackend({ services: [], features: [testModule()], + autoStop: false, }); expect(shutdownSpy).not.toHaveBeenCalled(); diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts index 9c9427e332..dbb4cff59a 100644 --- a/packages/backend-test-utils/src/next/wiring/TestBackend.ts +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -51,6 +51,7 @@ export interface TestBackendOptions< }, ]; features?: BackendFeature[]; + autoStop?: boolean; } const defaultServiceFactories = [ @@ -59,6 +60,8 @@ const defaultServiceFactories = [ lifecycleFactory(), ]; +const backendInstances = new Array(); + /** @alpha */ export async function startTestBackend< TServices extends any[], @@ -68,6 +71,7 @@ export async function startTestBackend< services = [], extensionPoints = [], features = [], + autoStop = true, ...otherOptions } = options; @@ -103,6 +107,10 @@ export async function startTestBackend< services: factories, }); + if (autoStop) { + backendInstances.push(backend); + } + backend.add({ id: `---test-extension-point-registrar`, register(reg) { @@ -122,3 +130,27 @@ export async function startTestBackend< return backend; } + +let registered = false; +function registerTestHooks() { + if (typeof afterEach !== 'function') { + return; + } + if (registered) { + return; + } + registered = true; + + afterEach(async () => { + for (const backend of backendInstances) { + try { + await backend.stop(); + } catch (error) { + console.error(`Failed to stop backend after test, ${error}`); + } + } + backendInstances.length = 0; + }); +} + +registerTestHooks();