Imported from equinor/fusion-skills (
skills/.experimental/fusion-framework-mocking/SKILL.md). Install upstream withnpx skills add equinor/fusion-skills --skill fusion-framework-mocking. Copyright stays with the author (MIT).
Fusion Framework Mocking
When to use
Use when a test needs deterministic Fusion Framework module state — a signed-in user, a current context, seeded feature flags/bookmarks, or faked HTTP responses — without a real Entra ID tenant, service registry, or backend.
Typical triggers:
- "How do I mock
useAccessToken/ sign in a test user?" - "Seed a current context for this test"
- "Fake this HTTP endpoint's response"
- "Mock service discovery so the app doesn't hit the network"
- "Add a mock for my own module"
- "Test signed-out / login / logout behavior"
- "Assert a middleware was called"
Implicit triggers:
- A test imports
mockFramework,mockAppModules, or any@equinor/fusion-framework-module-*/mockentry point - A test needs the app to boot without real credentials or a running backend
- Writing or reviewing a
*.mock.ts/mock-configurator file for a Fusion module
When not to use
- Rendering a component/hook or configuring Vitest/Browser Mode — use
fusion-framework-testing dev-server.config.tsAPI mocking/proxying for localffc app dev— that is dev-time only, unrelated to test-time module mocks; seefusion-developer-app- Asserting on one specific call (arguments, call count, reset) — that is the test runner's job (
vi.spyOn,vi.fn); this skill only covers seeding module state - Backend/service-repo test doubles (different repo, different stack)
Required inputs
Mandatory
- Which boundary needs faking: auth, service discovery, context, bookmarks, feature flags, HTTP, analytics, telemetry, app manifest, or a custom module
- Test scope: parent framework (
mockFramework), an app's own modules (mockAppModules), or a bespoke module graph (a module's ownenable*Mock)
Conditional
- Signed-in user details (name, username, specific token claims) when auth matters
- Whether the test must stay fully offline (every expected request needs an answering middleware)
- Whether an OpenAPI document already describes the API under test
Instructions
Step 1 — Understand the mocking design
Read references/framework-and-app-mocks.md for the design rules before writing a mock:
- Only the client (the object doing network I/O) is substituted. Providers, configurators,
schema validation, and module
initializeall run for real — a test still catches wiring mistakes. - Mocks live beside the module they replace, at that module's own
/mockentry point.@equinor/fusion-framework/mockonly composes the built-in set; it contains no mock logic of its own. - There is no Fusion mocking API for individual calls. Mock clients are plain classes with
ordinary methods — use
vi.spyOn,bun:test'sspyOn, or Node'st.mock.methoddirectly.
Step 2 — Pick the right layer
| Test scope | Use | Import |
|---|---|---|
| Parent framework / portal-level modules together | mockFramework |
@equinor/fusion-framework/mock |
| An app's own modules (no React) | mockAppModules |
@equinor/fusion-framework-app/mock |
| One module in a bespoke module graph | that module's enable*Mock |
@equinor/fusion-framework-module-*/mock |
| React hooks/components consuming app modules | render helpers (out of scope here) | see fusion-framework-testing |
import { mockFramework } from '@equinor/fusion-framework/mock';
const fusion = await mockFramework((configurator) => {
configurator.msal.setAccount({ name: 'Ada Lovelace' });
configurator.context.setCurrentContext({ id: 'project-a', type: { id: 'ProjectMaster' }, value: {} });
configurator.serviceDiscovery.addService({ key: 'catalog' });
});
mockFramework initializes every module FrameworkConfigurator declares (event, auth,
http, serviceDiscovery, context, telemetry) with zero configuration — a default signed-in
Test User and offline service resolution out of the box.
Step 3 — Seed the module the test needs
Use references/module-mocks.md for the full per-module table (auth, service discovery, context,
bookmark, feature flag, analytics, telemetry, app manifest) with defaults, builder methods, and
signed-out/token-exact recipes.
Step 4 — Fake HTTP responses
Use references/http-and-openapi-mocks.md to choose between a hand-written
configurator.http.addMiddleware(...), createRouterMiddleware for several routes, or
createOpenApiMockMiddleware (backed by @equinor/fusion-openapi-mock) for a whole OpenAPI
document. An unmatched request always falls through to next(uri, init) and eventually the real
network — a fully offline test must answer every request it expects.
Step 5 — Add a mock for a custom module (when needed)
Use references/custom-module-mocks.md when the module under test is not one of the built-ins —
covers the client seam (setClient), builder-owned configuration, and exposing a
configurator.<yourModule> accessor via FrameworkMockConfigurator's _pin/_getConfig.
Step 6 — Verify
- The mocked boundary is the client only — configurator/provider/validation are real
- Determinism: tokens and resolved services are identical across runs (no
Date.now()-derived assertions without seeding) - Every expected HTTP request has an answering middleware, or the test intentionally allows fallthrough
- Call-level assertions use the test runner's own spy tooling, not an invented Fusion API
Expected output
- Test code that seeds Fusion module state through the correct
/mockentry point - A stated choice of layer (
mockFramework/mockAppModules/ moduleenable*Mock) and why - HTTP faking strategy chosen (hand-written middleware, router, or OpenAPI) and its offline guarantees
- Any custom-module mock wiring, if applicable
Safety & constraints
Never:
- Invent a Fusion-specific mocking API for individual call assertions — that is the test runner's job
- Treat an unsigned mock JWT (
createMockToken/MSAL mock output) as valid outside a test - Replace a module's provider or configurator wholesale when only its client needs faking
- Assume
setResolveUnknownServices(false)is safe without declaring every service the framework itself resolves at start-up (e.g.context)
Always:
- Prefer the smallest mock boundary that still exercises the behavior under test
- Cite the real package/export used (e.g.
enableContextMockfrom@equinor/fusion-framework-module-context/mock) rather than inventing one - Note when a test intentionally allows network fallthrough vs. when it must stay fully offline