填写这份《一分钟调查》,帮我们(开发组)做得更好!去填写Home

测试管道

Testing Pipes

你可以在没有 Angular 测试工具的情况下测试管道

You can test pipes without the Angular testing utilities.

对于本测试指南中描述的范例应用,参阅范例应用范例应用

For the sample app that the testing guides describe, see thesample appsample app.

要了解本测试指南中涉及的测试特性,请参阅teststests

For the tests features in the testing guides, seeteststests.

测试 TitleCasePipe

Testing the TitleCasePipe

这个管道类有一个方法 transform ,它把输入值变成一个转换后的输出值。 transform 的实现很少会与 DOM 交互。除了 @Pipe 元数据和一个接口之外,大多数管道都不依赖于 Angular。

A pipe class has one method, transform, that manipulates the input value into a transformed output value. The transform implementation rarely interacts with the DOM. Most pipes have no dependence on Angular other than the @Pipe metadata and an interface.

考虑一个 TitleCasePipe ,它会把每个单词的第一个字母大写。这里是通过正则表达式实现的。

Consider a TitleCasePipe that capitalizes the first letter of each word. Here's an implementation with a regular expression.

import { Pipe, PipeTransform } from '@angular/core'; @Pipe({name: 'titlecase', pure: true}) /** Transform to Title Case: uppercase the first letter of the words in a string. */ export class TitleCasePipe implements PipeTransform { transform(input: string): string { return input.length === 0 ? '' : input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() )); } }
app/shared/title-case.pipe.ts
      
      import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'titlecase', pure: true})
/** Transform to Title Case: uppercase the first letter of the words in a string. */
export class TitleCasePipe implements PipeTransform {
  transform(input: string): string {
    return input.length === 0 ? '' :
      input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() ));
  }
}
    

任何使用正则表达式的东西都值得彻底测试。使用简单的 Jasmine 来探索预期的案例和边缘情况。

Anything that uses a regular expression is worth testing thoroughly. Use simple Jasmine to explore the expected cases and the edge cases.

describe('TitleCasePipe', () => { // This pipe is a pure, stateless function so no need for BeforeEach const pipe = new TitleCasePipe(); it('transforms "abc" to "Abc"', () => { expect(pipe.transform('abc')).toBe('Abc'); }); it('transforms "abc def" to "Abc Def"', () => { expect(pipe.transform('abc def')).toBe('Abc Def'); }); // ... more tests ... });
app/shared/title-case.pipe.spec.ts
      
      describe('TitleCasePipe', () => {
  // This pipe is a pure, stateless function so no need for BeforeEach
  const pipe = new TitleCasePipe();

  it('transforms "abc" to "Abc"', () => {
    expect(pipe.transform('abc')).toBe('Abc');
  });

  it('transforms "abc def" to "Abc Def"', () => {
    expect(pipe.transform('abc def')).toBe('Abc Def');
  });

  // ... more tests ...
});
    

编写 DOM 测试来支持管道测试

Writing DOM tests to support a pipe test

这些都是对管道进行隔离测试的。他们无法判断当 TitleCasePipe 应用于组件中时是否能正常运行。

These are tests of the pipe in isolation. They can't tell if the TitleCasePipe is working properly as applied in the application components.

考虑添加这样的组件测试:

Consider adding component tests such as this one:

it('should convert hero name to Title Case', () => { // get the name's input and display elements from the DOM const hostElement = fixture.nativeElement; const nameInput: HTMLInputElement = hostElement.querySelector('input'); const nameDisplay: HTMLElement = hostElement.querySelector('span'); // simulate user entering a new name into the input box nameInput.value = 'quick BROWN fOx'; // Dispatch a DOM event so that Angular learns of input value change. // In older browsers, such as IE, you might need a CustomEvent instead. See // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill nameInput.dispatchEvent(new Event('input')); // Tell Angular to update the display binding through the title pipe fixture.detectChanges(); expect(nameDisplay.textContent).toBe('Quick Brown Fox'); });
app/hero/hero-detail.component.spec.ts (pipe test)
      
      it('should convert hero name to Title Case', () => {
  // get the name's input and display elements from the DOM
  const hostElement = fixture.nativeElement;
  const nameInput: HTMLInputElement = hostElement.querySelector('input');
  const nameDisplay: HTMLElement = hostElement.querySelector('span');

  // simulate user entering a new name into the input box
  nameInput.value = 'quick BROWN  fOx';

  // Dispatch a DOM event so that Angular learns of input value change.
  // In older browsers, such as IE, you might need a CustomEvent instead. See
  // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
  nameInput.dispatchEvent(new Event('input'));

  // Tell Angular to update the display binding through the title pipe
  fixture.detectChanges();

  expect(nameDisplay.textContent).toBe('Quick Brown  Fox');
});