From 7da3b799e8012eb0cfe0dd164706ea68750cc920 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 28 Aug 2024 14:30:47 +0200 Subject: [PATCH 1/3] Add mockServices docs Signed-off-by: Johan Haals --- .../02-testing.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md index addcc72c84..912ffbba4d 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -31,17 +31,20 @@ import { myPlugin } from './plugin.ts'; describe('myPlugin', () => { it('can serve values from config', async () => { const fakeConfig = { myPlugin: { value: 7 } }; + const mockLogger = mockServices.logger.mock(); const { server } = await startTestBackend({ features: [ myPlugin(), mockServices.rootConfig.factory({ data: fakeConfig }), + mockLogger, ], }); const response = await request(server).get('/api/example/get-value'); expect(response.status).toBe(200); expect(response.body).toEqual({ value: 7 }); + expect(mockLogger.info).toHaveBeenCalledWith('Starting myPlugin'); }); }); ``` @@ -53,6 +56,31 @@ The returned server also has a `port()` method which returns the dynamically bound listening port. You can use this to perform lower level network interactions with the running test service. +### mock services + +The `mockServices` object provides a number of service factory functions satisfy plugin dependencies but also mocks to verify interactions between plugin and services. + +The following mock services are available: + +- `auth` +- `cache` +- `database` +- `discovery` +- `events` +- `httpAuth` +- `httpRouter` +- `lifecycle` +- `logger` +- `permissions` +- `rootConfig` +- `rootHealth` +- `rootHttpRouter` +- `rootLifecycle` +- `rootLogger` +- `scheduler` +- `urlReader` +- `userInfo` + ## Testing Remote Service Interactions If your backend plugin or service interacts with external services using HTTP From bf5fc74a69ca250bd910888dfd59cc77622be1f5 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Wed, 28 Aug 2024 15:44:19 +0200 Subject: [PATCH 2/3] Update docs/backend-system/building-plugins-and-modules/02-testing.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Johan Haals Co-authored-by: Fredrik Adelöw Signed-off-by: Johan Haals --- docs/backend-system/building-plugins-and-modules/02-testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md index 912ffbba4d..3e06db561a 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -58,7 +58,7 @@ interactions with the running test service. ### mock services -The `mockServices` object provides a number of service factory functions satisfy plugin dependencies but also mocks to verify interactions between plugin and services. +The `mockServices` object from `@backstage/backend-test-utils` provides a number of service factory functions that you can use to verify interactions between plugin and services. The following mock services are available: From 2230e4cf3307f389bdc72246a773ce4bb84cc901 Mon Sep 17 00:00:00 2001 From: Johan Haals Date: Thu, 29 Aug 2024 09:46:30 +0200 Subject: [PATCH 3/3] Extend mockServices documentation Signed-off-by: Johan Haals --- .../02-testing.md | 85 ++++++++++++++----- 1 file changed, 65 insertions(+), 20 deletions(-) diff --git a/docs/backend-system/building-plugins-and-modules/02-testing.md b/docs/backend-system/building-plugins-and-modules/02-testing.md index 3e06db561a..38107f0242 100644 --- a/docs/backend-system/building-plugins-and-modules/02-testing.md +++ b/docs/backend-system/building-plugins-and-modules/02-testing.md @@ -58,28 +58,73 @@ interactions with the running test service. ### mock services -The `mockServices` object from `@backstage/backend-test-utils` provides a number of service factory functions that you can use to verify interactions between plugin and services. +The [`mockServices`](https://backstage.io/docs/reference/backend-test-utils.mockservices) object from `@backstage/backend-test-utils` provides service factory functions, and mocks for all core services that you can use to verify interactions between plugin and services. -The following mock services are available: +All mock services provide a factory function that is sufficient for most tests. Here's an example: -- `auth` -- `cache` -- `database` -- `discovery` -- `events` -- `httpAuth` -- `httpRouter` -- `lifecycle` -- `logger` -- `permissions` -- `rootConfig` -- `rootHealth` -- `rootHttpRouter` -- `rootLifecycle` -- `rootLogger` -- `scheduler` -- `urlReader` -- `userInfo` +```ts +const fakeConfig = { myPlugin: { value: 7 } }; +const { server } = await startTestBackend({ + features: [ + // Will provide access to the default urlReaders automatically. + mockServices.urlReader.factory(), + // Some factories accept options, in this example we provide some fake config. + mockServices.rootConfig.factory({ data: fakeConfig }), + ], +}); +``` + +There might be situations where you want to mock a service implementation to verify interactions, in those cases you can use the `mock` function to get a mock object that you can interact with. Here's an example: + +```ts +import { mockServices, startTestBackend } from '@backstage/backend-test-utils'; +import { myPlugin } from './plugin.ts'; + +describe('myPlugin', () => { + it('should call use UrlReader', async () => { + const mockReader = mockServices.urlReader.mock(); + + await startTestBackend({ + features: [myPlugin(), mockReader], + }); + + expect(mockReader.readUrl).toHaveBeenCalledWith('https://backstage.io'); + }); + + it('should call use UrlReader again', async () => { + const partialImpl = jest.fn(); + await startTestBackend({ + features: [ + myPlugin(), + // You could also supply partial implementations to the mock function. + mockServices.urlReader.mock({ readUrl: partialImpl }), + ], + }); + expect(partialImpl).toHaveBeenCalledWith('https://backstage.io'); + }); +}); +``` + +Available services: + +- [`auth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.auth/) +- [`cache`](https://backstage.io/docs/reference/backend-test-utils.mockservices.cache/) +- [`database`](https://backstage.io/docs/reference/backend-test-utils.mockservices.database/) +- [`discovery`](https://backstage.io/docs/reference/backend-test-utils.mockservices.discovery/) +- [`events`](https://backstage.io/docs/reference/backend-test-utils.mockservices.events/) +- [`httpAuth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.httpAuth/) +- [`httpRouter`](https://backstage.io/docs/reference/backend-test-utils.mockservices.httpRouter/) +- [`lifecycle`](https://backstage.io/docs/reference/backend-test-utils.mockservices.lifecycle/) +- [`logger`](https://backstage.io/docs/reference/backend-test-utils.mockservices.logger/) +- [`permissions`](https://backstage.io/docs/reference/backend-test-utils.mockservices.permissions/) +- [`rootConfig`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootConfig/) +- [`rootHealth`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootHealth/) +- [`rootHttpRouter`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootHttpRouter/) +- [`rootLifecycle`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootLifecycle/) +- [`rootLogger`](https://backstage.io/docs/reference/backend-test-utils.mockservices.rootLogger/) +- [`scheduler`](https://backstage.io/docs/reference/backend-test-utils.mockservices.scheduler/) +- [`urlReader`](https://backstage.io/docs/reference/backend-test-utils.mockservices.urlReader/) +- [`userInfo`](https://backstage.io/docs/reference/backend-test-utils.mockservices.userInfo/) ## Testing Remote Service Interactions