0Pricing
Angular Academy · 课时

测试输入、输出和 DOM

断言渲染输出和事件

测试输入、输出和 DOM 是 CoddyKit 上的免费 Angular Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Angular Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Angular Academy 课程共包含 4 节课。

测试组件契约

组件通过输入(传入数据)、输出(传出事件)以及渲染后的 DOM进行通信。良好的组件测试应驱动这三个接口,并验证可见结果,而不是内部实现细节。

设置输入

为组件实例的输入属性赋值,然后调用 detectChanges() 重新渲染。对于信号输入,请通过 fixture.componentRef.setInput() 设置。

fixture.componentInstance.label = 'Save';
fixture.detectChanges();
// signal inputs:
fixture.componentRef.setInput('label', 'Save');
fixture.detectChanges();

使用 querySelector 读取 DOM

使用 fixture.nativeElement.querySelector() 查找已渲染的元素,并断言其文本或属性。

fixture.componentRef.setInput('label', 'Save');
fixture.detectChanges();
const btn = fixture.nativeElement.querySelector('button');
expect(btn.textContent.trim()).toBe('Save');

DebugElement 与 By.css

fixture.debugElement.query(By.css(...)) 返回一个 DebugElement 包装器。其 .nativeElement 是 DOM 节点,并且您可以使用跨平台效果更稳定的高级查询。

import { By } from '@angular/platform-browser';

const de = fixture.debugElement.query(By.css('.title'));
expect(de.nativeElement.textContent).toContain('Hello');

使用 queryAll 处理列表

对于重复元素(例如 @for 循环),请使用 queryAll 获取所有匹配项并检查数量。

const items = fixture.debugElement.queryAll(By.css('li'));
expect(items.length).toBe(3);
expect(items[0].nativeElement.textContent).toContain('First');

模拟点击

触发 DOM 事件来测试交互。对 DebugElement 使用 triggerEventHandler,或调用原生的 .click(),然后调用 detectChanges()。

const btn = fixture.debugElement.query(By.css('button'));
btn.triggerEventHandler('click');
fixture.detectChanges();
expect(fixture.componentInstance.count).toBe(1);

测试输出事件

在触发应当发出事件的操作之前,订阅组件的输出(EventEmitter 或输出信号)。

let emitted: string | undefined;
fixture.componentInstance.saved.subscribe((v: string) => (emitted = v));
fixture.debugElement.query(By.css('button')).triggerEventHandler('click');
expect(emitted).toBe('done');

断言属性和类

您可以验证取决于输入的条件类和属性。

fixture.componentRef.setInput('active', true);
fixture.detectChanges();
const el = fixture.nativeElement.querySelector('.tab');
expect(el.classList.contains('active')).toBe(true);

更新表单输入

要测试文本字段,请设置输入值,并分发一个 input 事件,使 Angular 绑定得到更新。

const input = fixture.nativeElement.querySelector('input');
input.value = 'hello';
input.dispatchEvent(new Event('input'));
fixture.detectChanges();
expect(fixture.componentInstance.text).toBe('hello');

为什么每次更改后都要调用 detectChanges

基于 Zone 和无 Zone 的测试都要求您在修改状态后显式调用 detectChanges(),因为测试是在 Angular 自动更新周期之外运行的。忘记调用它是“我的断言看到了过时 DOM”这一问题的首要原因。

测试行为,而非内部实现

请优先断言渲染输出和发出的事件,而不是私有字段。这样可以让测试更稳定:只要用户可见的行为保持不变,内部实现的重构就不应破坏测试。

快速检查

哪个 API 会为您提供 DebugElement?

回顾

您通过 setInput 驱动输入,使用 querySelector 和 By.css 读取 DOM,通过订阅捕获输出,并模拟了点击和输入事件。每次更改后都要调用 detectChanges(),并断言用户可见的行为。

常见问题解答

「测试输入、输出和 DOM」课时是免费的吗?

是的 — 「测试输入、输出和 DOM」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Angular Academy 课程的其余内容,请升级到 CoddyKit PRO。 Angular Academy 课程共包含 4 节课。

「测试输入、输出和 DOM」这节课中我会学到什么?

断言渲染输出和事件 你通过在浏览器中直接运行的动手代码来练习 Angular Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Angular Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Angular Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「测试输入、输出和 DOM」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Angular Academy 课中编写并运行代码吗?

能。每节 Angular Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. TestBed 与组件夹具
  2. 测试输入、输出和 DOM
  3. 模拟服务与依赖项
  4. 测试信号与异步代码
← 返回 Angular Academy