frontend-test-utils: also add apis option to renderTestApp

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-02-03 00:21:07 +01:00
parent 062e9dcf09
commit 1911ebac7f
3 changed files with 47 additions and 7 deletions
+12 -1
View File
@@ -2,7 +2,7 @@
'@backstage/frontend-test-utils': patch
---
Added an `apis` option to `createExtensionTester` and `renderInTestApp` to override APIs when testing extensions. Use the `mockApis` helpers to create mock implementations:
Added an `apis` option to `createExtensionTester`, `renderInTestApp`, and `renderTestApp` to override APIs when testing extensions. Use the `mockApis` helpers to create mock implementations:
```typescript
import { identityApiRef } from '@backstage/frontend-plugin-api';
@@ -27,4 +27,15 @@ renderInTestApp(<MyComponent />, {
],
],
});
// Override APIs in renderTestApp
renderTestApp({
extensions: [myExtension],
apis: [
[
identityApiRef,
mockApis.identity({ userEntityRef: 'user:default/guest' }),
],
],
});
```
+4 -3
View File
@@ -126,16 +126,17 @@ export function renderInTestApp<TApiPairs extends any[] = any[]>(
): RenderResult;
// @public
export function renderTestApp(
options: RenderTestAppOptions,
export function renderTestApp<TApiPairs extends any[] = any[]>(
options: RenderTestAppOptions<TApiPairs>,
): RenderResult<testingLibraryDomTypesQueries, HTMLElement, HTMLElement>;
// @public
export type RenderTestAppOptions = {
export type RenderTestAppOptions<TApiPairs extends any[] = any[]> = {
config?: JsonObject;
extensions?: ExtensionDefinition<any>[];
features?: FrontendFeature[];
initialRouteEntries?: string[];
apis?: readonly [...TestApiPairs<TApiPairs>];
};
// @public
@@ -17,6 +17,7 @@
import { createSpecializedApp } from '@backstage/frontend-app-api';
import {
coreExtensionData,
createApiFactory,
createFrontendModule,
createFrontendPlugin,
ExtensionDefinition,
@@ -28,6 +29,9 @@ import { JsonObject } from '@backstage/types';
import { ConfigReader } from '@backstage/config';
import { MemoryRouter } from 'react-router-dom';
import { RouterBlueprint } from '@backstage/plugin-app-react';
import { type TestApiPairs } from '../utils';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import type { CreateSpecializedAppInternalOptions } from '../../../frontend-app-api/src/wiring/createSpecializedApp';
const DEFAULT_MOCK_CONFIG = {
app: { baseUrl: 'http://localhost:3000' },
@@ -39,7 +43,7 @@ const DEFAULT_MOCK_CONFIG = {
*
* @public
*/
export type RenderTestAppOptions = {
export type RenderTestAppOptions<TApiPairs extends any[] = any[]> = {
/**
* Additional configuration passed to the app when rendering elements inside it.
*/
@@ -58,6 +62,23 @@ export type RenderTestAppOptions = {
* Initial route entries to use for the router.
*/
initialRouteEntries?: string[];
/**
* API overrides to provide to the test app. Use `mockApis` helpers
* from `@backstage/frontend-test-utils` to create mock implementations.
*
* @example
* ```ts
* import { identityApiRef } from '@backstage/frontend-plugin-api';
* import { mockApis } from '@backstage/frontend-test-utils';
*
* renderTestApp({
* apis: [[identityApiRef, mockApis.identity({ userEntityRef: 'user:default/guest' })]],
* extensions: [...],
* })
* ```
*/
apis?: readonly [...TestApiPairs<TApiPairs>];
};
const appPluginOverride = appPlugin.withOverrides({
@@ -74,7 +95,9 @@ const appPluginOverride = appPlugin.withOverrides({
*
* @public
*/
export function renderTestApp(options: RenderTestAppOptions) {
export function renderTestApp<TApiPairs extends any[] = any[]>(
options: RenderTestAppOptions<TApiPairs>,
) {
const extensions = [...(options.extensions ?? [])];
const features: FrontendFeature[] = [
@@ -111,7 +134,12 @@ export function renderTestApp(options: RenderTestAppOptions) {
data: options?.config ?? DEFAULT_MOCK_CONFIG,
},
]),
});
__internal: options?.apis && {
apiFactoryOverrides: options.apis.map(([apiRef, implementation]) =>
createApiFactory(apiRef, implementation),
),
},
} as CreateSpecializedAppInternalOptions);
return render(
app.tree.root.instance!.getData(coreExtensionData.reactElement),