单元测试项目从 Observable 中过滤掉(Jasmine/RxJS)

eri*_*rin 4 unit-testing observable jasmine rxjs angular

我正在使用 Jasmine/Karma 针对 Angular 服务进行单元测试。我想确认我的服务是否正确过滤了项目。

例如,如果我有一项服务可以吸引特定年龄以上的人,那么它

  1. 应该返回超过最低年龄的人(阳性案例)
  2. 不应返回最低年龄以下的人(负面情况)

这是我正在努力测试的#2。

服务:

    getPeople(minAge: number): Observable<string> {
        const source = Observable.from([
            { name: 'Joe', age: 30 },
            { name: 'Frank', age: 20 },
            { name: 'Ryan', age: 50 }
        ]);
        return source
            .filter(person => person.age >= minAge)
            .map(person => person.name);
    }
Run Code Online (Sandbox Code Playgroud)

积极的单元测试

    it('should return people over 30', () => {
        const service = new MyService();
        const minAge = 30;
        service.getPeople(minAge).subscribe(people => {
            expect(people.length).toBeGreaterThan(0);
        });
    });
Run Code Online (Sandbox Code Playgroud)

和负面的单元测试

it('should not return people over 55', () => {
        const service = new MyService();
        const minAge = 55;
        service.getPeople(minAge).subscribe(people => {
            expect(people.length).toBe(0); // WE NEVER GET HERE!
        });
    });
Run Code Online (Sandbox Code Playgroud)

在负面情况下,Observable 永远不会返回任何东西,这是正确的。但是,我如何编写单元测试来确认这一点?

JB *_*zet 6

你的第一次测试是错误的。它测试发出的每个字符串的长度是否大于 0。这不应该是您测试的内容:即使您的代码发出“Frank”,测试也会通过。您应该测试的是发出的人名是“Joe”和“Ryan”:

const result: Array<string> = [];
service.getPeople(minAge).subscribe(people => {
  result.push(people);
});
expect(result).toEqual(['Joe', 'Ryan']); 
Run Code Online (Sandbox Code Playgroud)

您的第二个测试并不是真正必要的,因为您的第一个测试会检查过滤结果是否正确,并且不会返回错误的名称。但如果你真的想保留它,那么如果调用 subscribe 回调,你应该使测试失败,因为不应该调用它:

service.getPeople(minAge).subscribe(people => {
  fail('should not be called');
});
Run Code Online (Sandbox Code Playgroud)