关于 fusion-framework-mocking
这是一个用于确定性测试 Fusion Framework 模块状态的技能,无需真实凭据或后端。它帮助开发者选择模拟层、设定模块状态并伪造 HTTP 响应。
主要功能
- 01模拟框架和应用模块
- 02设定认证、上下文和功能标志
- 03通过中间件伪造 HTTP 响应
- 04支持基于 OpenAPI 的模拟中间件
- 05指导自定义模块模拟
适用场景
- 01测试已登录和未登录行为
- 02在无后端环境下测试模块
- 03为测试提供确定性 HTTP 响应
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ equinor/ fusion-skills --skill fusion-framework-mocking安装后在 Claude Code 中输入/fusion-framework-mocking确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdreferences/custom-module-mocks.mdframework-and-app-mocks.mdhttp-and-openapi-mocks.mdmodule-mocks.md详细介绍
Fusion Framework 模拟
适用场景
当测试需要确定的 Fusion Framework 模块状态时使用,例如已登录用户、当前上下文、预置的功能标志/书签或伪造的 HTTP 响应,且不需要真实的 Entra ID 租户、服务注册表或后端。
典型触发场景:
- “如何模拟
useAccessToken/让测试用户登录?” - “为此测试预置当前上下文”
- “伪造此 HTTP 端点的响应”
- “模拟服务发现,避免应用访问网络”
- “为我自己的模块添加模拟”
- “测试已登出/登录/登出行为”
- “断言某个中间件已被调用”
隐式触发场景:
- 测试导入
mockFramework、mockAppModules或任何@equinor/fusion-framework-module-*/mock入口 - 测试需要在没有真实凭据或运行中的后端时启动应用
- 为 Fusion 模块编写或审查
*.mock.ts/模拟配置器文件
不适用场景
- 渲染组件/钩子或配置 Vitest/Browser Mode——使用
fusion-framework-testing - 通过
dev-server.config.ts为本地ffc app dev模拟/代理 API——这仅适用于开发时,与测试时的模块模拟无关;参见fusion-developer-app - 断言某一次特定调用(参数、调用次数、重置)——这是测试运行器的职责(
vi.spyOn、vi.fn);本指南仅涵盖预置模块状态 - 后端/服务仓库测试替身(不同仓库、不同技术栈)
必需输入
必填
- 需要伪造的边界:身份验证、服务发现、上下文、书签、功能标志、HTTP、分析、遥测、应用清单或自定义模块
- 测试范围:父级框架(
mockFramework)、应用自有模块(mockAppModules)或自定义模块图(模块自己的enable*Mock)
有条件必填
- 已登录用户的详细信息(姓名、用户名、特定令牌声明),适用于身份验证相关测试
- 测试是否必须完全离线(每个预期请求都需要有对应的中间件响应)
- OpenAPI 文档是否已描述被测 API
说明
第 1 步——了解模拟设计
编写模拟前,先阅读 references/framework-and-app-mocks.md 中的设计规则:
- 仅替换客户端(执行网络 I/O 的对象)。Provider、配置器、架构验证和模块
initialize均照常运行——测试仍能捕获接线错误。 - 模拟与其替换的模块放在一起,位于该模块自己的
/mock入口。@equinor/fusion-framework/mock仅组合内置模拟集;本身不包含模拟逻辑。 - 没有用于单次调用的 Fusion 模拟 API。模拟客户端是带有普通方法的普通类——直接使用
vi.spyOn、bun:test的spyOn或 Node 的t.mock.method。
第 2 步——选择正确的层级
| 测试范围 | 使用 | 导入 |
|---|---|---|
| 一起测试父级框架/门户级模块 | mockFramework | @equinor/fusion-framework/mock |
| 应用自有模块(不含 React) | mockAppModules | @equinor/fusion-framework-app/mock |
| 自定义模块图中的单个模块 | 该模块的 enable*Mock | @equinor/fusion-framework-module-*/mock |
| 使用应用模块的 React 钩子/组件 | 渲染辅助工具(此处不涵盖) | 参见 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 会以零配置初始化 FrameworkConfigurator 声明的所有模块(event、auth、http、serviceDiscovery、context、telemetry),并默认提供已登录的 Test User 和离线服务解析。
第 3 步——预置测试所需的模块
有关各模块的完整表格(身份验证、服务发现、上下文、书签、功能标志、分析、遥测、应用清单),以及默认值、构建器方法和已登出/精确令牌示例,请参阅 references/module-mocks.md。
步骤 4 — 伪造 HTTP 响应
使用 references/http-and-openapi-mocks.md,选择手写
configurator.http.addMiddleware(...)、为多个路由使用 createRouterMiddleware,或使用
由 @equinor/fusion-openapi-mock 支持、针对整个 OpenAPI 文档的 createOpenApiMockMiddleware。未匹配的请求总会传递给 next(uri, init),最终访问真实网络——完全离线的测试必须响应它预期的每个请求。
步骤 5 — 为自定义模块添加模拟(需要时)
当被测模块不是内置模块时,请使用 references/custom-module-mocks.md——其中涵盖客户端接缝(setClient)、由构建器持有的配置,以及通过 FrameworkMockConfigurator 的 _pin/_getConfig 暴露 configurator.<yourModule> 访问器。
步骤 6 — 验证
- 模拟边界仅限客户端——configurator/provider/validation 均使用真实对象
- 确定性:每次运行的令牌和解析后的服务都相同(若断言未使用种子固定的值,请勿依赖
Date.now()) - 每个预期的 HTTP 请求都有对应的响应中间件,或者测试明确允许请求继续传递
- 调用级断言使用测试运行器自带的 spy 工具,而非虚构的 Fusion API
预期输出
- 通过正确的
/mock入口为 Fusion 模块状态设定初始值的测试代码 - 明确说明选择的层(
mockFramework/mockAppModules/ 模块enable*Mock)及原因 - 选定的 HTTP 伪造策略(手写中间件、路由器或 OpenAPI)及其离线保障
- 适用时,提供自定义模块的模拟接线方式
安全与约束
切勿:
- 为单次调用断言虚构 Fusion 专用模拟 API——这应由测试运行器负责
- 在测试之外将未签名的模拟 JWT(
createMockToken/MSAL 模拟输出)视为有效令牌 - 当只需伪造客户端时,整体替换模块的 provider 或 configurator
- 在未声明框架自身启动时会解析的所有服务(例如
context)的情况下,假定setResolveUnknownServices(false)是安全的
始终:
- 优先选择仍能覆盖被测行为的最小模拟边界
- 引用实际使用的包/导出项(例如,来自
@equinor/fusion-framework-module-context/mock的enableContextMock),而非虚构名称 - 说明测试是有意允许网络请求继续传递,还是必须保持完全离线