ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Angular Material 的 MatDividerHarness 完整指南:divider 分隔线组件的测试 Harness API 与实战

Angular Material 的 MatDividerHarness 完整指南:divider 分隔线组件的测试 Harness API 与实战 Angular Material 的 MatDividerHarness 完整指南divider 分隔线组件的测试 Harness API 与实战【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/componentsMatDividerHarness是 Angular Material 为mat-divider分隔线组件提供的官方测试基础设施封装在angular/material_divider_testing入口中。本文以 goldens/material/divider/testing/index.api.md 的 API 报告为骨架结合本仓库中 divider 组件的源码与测试系统讲解该 Harness 的公开 API、底层实现原理、过滤条件用法与完整测试实战帮助你在 Angular 单元测试中稳定、可靠地验证分隔线的方向与 inset 状态。为什么需要 Divider 的 Component Harness在 Angular 组件测试中直接查询 DOM 存在两个痛点一是组件内部 DOM 结构可能随版本升级而变化导致测试选择器脆弱二是断言逻辑与 DOM 细节耦合难以维护。CDK 的 Component Harness 体系正是为了解决这一问题而设计测试通过 Harness 暴露的语义化 API 与组件交互即使内部 DOM 重构只要 Harness 契约不变测试就无需改动。MatDividerHarness是本仓库 src/material/divider/testing 目录下为mat-divider组件实现的专用 Harness它继承自angular/cdk/testing的ComponentHarness是 CDK Harness 体系的组成部分。与之配套的还有本仓库中其他组件的同类 Harness如 goldens/material/button/testing/index.api.md、goldens/material/list/testing/index.api.mdAPI 风格保持一致。API 总览angular/material_divider_testing 的公开面根据 goldens/material/divider/testing/index.api.mdAPI Extractor 自动生成的 API 报告不可手动编辑angular/material_divider_testing包只对外暴露两个成员DividerHarnessFilters查找过滤条件接口继承自BaseHarnessFilters当前为空扩展。MatDividerHarnessdivider 组件测试 Harness提供 1 个静态宿主选择器、1 个静态工厂方法和 2 个异步查询方法。该包的源码入口在 src/material/divider/testing/public-api.ts它统一导出了divider-harness与divider-harness-filters两个模块src/material/divider/testing/index.ts 再透传导出构成完整的包级公开 API。MatDividerHarness 成员逐一详解static hostSelector宿主元素选择器static hostSelector .mat-divider;见 src/material/divider/testing/divider-harness.ts。该选择器指向组件根元素上始终存在的mat-dividerCSS 类Harness 环境据此从 DOM 中定位候选宿主。注意hostSelector与组件选择器mat-divider不冲突——类名.mat-divider是 divider.ts 中 host 绑定固定写入的任何使用mat-divider标签的地方都会携带该 class因此 Harness 总能命中。static with()构造过滤谓词static with(options: DividerHarnessFilters {}) { return new HarnessPredicate(MatDividerHarness, options); }见 divider-harness.ts。with()接收DividerHarnessFilters并返回HarnessPredicateMatDividerHarness供loader.getAllHarnesses(MatDividerHarness.with(...))之类的调用链使用。由于DividerHarnessFilters目前是空扩展接口见 divider-harness-filters.ts它实际可用的是BaseHarnessFilters提供的通用过滤能力定义于 src/cdk/testing/component-harness.ts字段类型说明selectorstring \| undefined仅匹配宿主元素符合该 CSS 选择器的实例ancestorstring \| undefined仅匹配嵌套在符合该选择器的元素之下的实例这两个字段的语义在HarnessPredicate构造函数中有明确实现component-harness.tsancestor决定候选集合的 DOM 范围selector则对候选宿主逐一再做matchesSelector校验。这意味着即使未来需要按自定义属性过滤 divider也可以通过selector实现无需改动 Harness 本身。getOrientation()读取分隔线方向async getOrientation(): Promisehorizontal | vertical { return (await this.host()).getAttribute(aria-orientation) as Promise horizontal | vertical ; }见 divider-harness.ts。该方法直接读取宿主元素的aria-orientation属性。该属性的来源在组件侧 divider.ts 的 host 绑定中[attr.aria-orientation]: vertical ? vertical : horizontal。因此 Harness 返回的值始终是这两个字面量之一与组件的vertical输入严格对应。isInset()判断是否为嵌入分隔线async isInset(): Promiseboolean { return (await this.host()).hasClass(mat-divider-inset); }见 divider-harness.ts。该方法检测宿主元素是否带有mat-divider-inset类。同样地这个 class 由 divider.ts 的[class.mat-divider-inset]: inset绑定生成与组件的inset输入一一对应。组件侧实现Harness 依赖的 DOM 契约MatDividerHarness的每个方法都建立在对 src/material/divider/divider.ts 中 host 绑定的依赖之上这是理解其原理的关键Component({ selector: mat-divider, host: { role: separator, [attr.aria-orientation]: vertical ? vertical : horizontal, [class.mat-divider-vertical]: vertical, [class.mat-divider-horizontal]: !vertical, [class.mat-divider-inset]: inset, class: mat-divider, }, template: , ... }) export class MatDivider { Input() get/set vertical // 通过 coerceBooleanProperty 布尔化 Input() get/set inset // 通过 coerceBooleanProperty 布尔化 }可以看到MatDivider是一个无模板组件template: 全部表现由宿主元素的 class 与 ARIA 属性承载vertical与inset输入均使用angular/cdk/coercion的coerceBooleanProperty进行布尔化因此模板中写insettrue或[inset]true均可方向属性aria-orientation既是辅助技术读取的语义信息也是 HarnessgetOrientation()的数据源一条属性同时服务可访问性与可测试性。组件侧的 API 报告见 goldens/material/divider/index.api.md其中MatDivider与MatDividerModule的公开面含inset/vertical输入及BidiModule依赖与之相互印证。实战在 Testbed 中驱动 MatDividerHarness仓库自带的单元测试 src/material/divider/testing/divider-harness.spec.ts 是标准用法的最佳范本describe(MatDividerHarness, () { let fixture: ComponentFixtureDividerHarnessTest; let loader: HarnessLoader; beforeEach(() { fixture TestBed.createComponent(DividerHarnessTest); fixture.detectChanges(); loader TestbedHarnessEnvironment.loader(fixture); }); it(should load all divider harnesses, async () { const dividers await loader.getAllHarnesses(MatDividerHarness); expect(dividers.length).toBe(2); }); it(should check if divider is inset, async () { const dividers await loader.getAllHarnesses(MatDividerHarness); expect(await dividers[0].isInset()).toBe(false); expect(await dividers[1].isInset()).toBe(true); }); it(should get divider orientation, async () { const dividers await loader.getAllHarnesses(MatDividerHarness); expect(await dividers[0].getOrientation()).toBe(horizontal); expect(await dividers[1].getOrientation()).toBe(vertical); }); });测试用组件模板同时渲染了两种形态mat-divider/mat-divider mat-divider inset vertical/mat-divider实战要点归纳环境初始化通过TestbedHarnessEnvironment.loader(fixture)来自angular/cdk/testing/testbed创建HarnessLoader这是 CDK 提供的两个 Harness 运行环境之一另一个是 Selenium WebDriver 环境用于端到端测试批量获取getAllHarnesses(MatDividerHarness)依据hostSelector .mat-divider找到全部 2 个实例返回顺序与 DOM 顺序一致定向过滤若只需某个范围内的 divider可组合MatDividerHarness.with({ancestor: mat-list})或{selector: .mat-divider-vertical}使用也可改用getHarness()/getAllHarnesses()配合谓词断言语义化用isInset()、getOrientation()代替直接检查 class 与属性测试意图更清晰且不受内部实现调整影响异步 APIHarness 方法一律返回 Promise断言处需await。在列表场景中的实际验证src/material/divider/divider.md 展示了 inset divider 的典型业务场景——在列表中使用嵌入分隔线区分条目同时建议不要给最后一项加 inset以免与段落分隔线重叠。对应地测试中可以这样验证const listDividers await loader.getAllHarnesses( MatDividerHarness.with({ancestor: mat-list}), ); for (const d of listDividers) { expect(await d.isInset()).toBe(true); }无障碍语义separator 角色的双重价值MatDivider应用了 ARIAroleseparator属性实现了非可聚焦类型的分隔符语义专门用于区分内容区块见 divider.md 的 Accessibility 小节与 divider.ts 的 host 绑定。这一设计对测试同样有意义aria-orientation属性同时服务于屏幕阅读器与 Harness 的getOrientation()说明在 Angular Material 中可访问性与可测试性共享同一套语义契约这是编写组件时值得借鉴的模式。总结与进一步探索MatDividerHarness是理解 Angular Material Harness 设计的最小而完整的范本它以静态hostSelector定位宿主以with()谓词支持过滤以getOrientation()/isInset()暴露语义化查询能力全程与组件 host 绑定保持契约一致。想深入更多内容可以参考Harness 基类与谓词机制src/cdk/testing/component-harness.tsTestbed 环境实现src/cdk/testing/testbed组件本体与模块src/material/divider/divider.ts、src/material/divider/divider-module.ts样式实现src/material/divider/divider.scss含mat-divider-vertical、mat-divider-horizontal、mat-divider-inset视觉规则主题定制src/material/divider/_divider-theme.scss【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表