测试Class与Pipe

Angular中组件、指令、管道等皆为对象,所以知道如何测试一个类就足够了。 我们有个简单的服务类AuthService,这个类将被注入到模板对象中。

app/auth.service.ts

1
2
3
4
5
export class AuthService {
  isAuthenticated(): boolean {
    return !!localStorage.getItem('token');
  }
}

方法isAuthenticated在localStorage中存在token时返回true。
另外再创建一个spec测试类auth.service.spec.ts,内容如下:
app/auth.service.spec.ts

1
2
3
4
import {AuthService} from './auth.service'; 

describe('Service: Auth', () => { 
});

Setup & teardown

  • Setup: 为每个测试准备测试环境,可以在beforeEach、beforeAll中实现
  • Teardown: 测试代码执行之后清理测试环境,可以下afterEach、afterAll中实现

app/auth.service.spec.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
describe('Service: Auth', () => {
  let service: AuthService;

  beforeEach(() => { //每个spec执行之前创建新的AuthService实例
    service = new AuthService();
  });

  afterEach(() => { //每个spec执行完之后销毁AuthService对象并清除token
    service = null;
    localStorage.removeItem('token');
  });
});

创建测试用例

创建一个测试用例:检查isAuthenticated在有token时是否会返回true

1
2
3
4
it('should return true from isAuthenticated when there is a token', () => { //it方法的第一个参数描述本测试用例的核心逻辑,在测试报告中一目了然
  localStorage.setItem('token', '1234'); 
  expect(service.isAuthenticated()).toBeTruthy(); //使用断言判断方法返回结果为true
});

再增加一个测试用例:没有token时返回false

1
2
3
it('should return false from isAuthenticated when there is no token', () => {
  expect(service.isAuthenticated()).toBeFalsy();//每个测试用例结束后都会清理token,所以不需要任何条件准备
});

执行测试

命令行中执行 ng test

结果如图

管道 Pipes

管道应该是Angular中最简单的部分了:一个类中定义一个方法。使用上面已掌握的测试基础我们完全可以实现对管道的测试。

创建一个DefaultPipe管道,其功能是给模板中变量提供默认值

1
{{ image | default:"http://example.com/default-image.png" }}

DefaultPipe代码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
    name: 'default'
})
export class DefaultPipe implements PipeTransform {

    transform(value: string, fallback: string, forceHttps: boolean = false): string {
        let image = '';
        if (value) {
            image = value;
        } else {
            image = fallback;
        }
        if (forceHttps) {
            if (image.indexOf('https') === -1) {
                image = image.replace('http', 'https');
            }
        }
        return image;
    }
}

对应的测试套件:

1
2
3
4
5
6
7
describe('Pipe: Default', () => {
  let pipe: DefaultPipe;

  beforeEach(() => {//创建一个管道实例对象
    pipe = new DefaultPipe();
  });
});

管道只有一个transform方法,我们只需要对这个方法进行测试,输入参数并检查输出结果。

第一个测试用例:管道没有接收到值时返回设定的默认值

1
2
3
it('providing no value returns fallback', () => {
  expect(pipe.transform('', 'http://place-hold.it/300')).toBe('http://place-hold.it/300');
});

测试代码中我们第一个参数传入的空字符串,并期望其返回值为第二个参数。

如果管道中需要使用外部依赖,最好使用Angular的TestBed来进行测试。TestBed随后章节中会讲述。