【问题标题】:Unit testing that items get filtered out of Observable (Jasmine/RxJS)从 Observable 中过滤掉项目的单元测试 (Jasmine/RxJS)
【发布时间】:2018-07-01 13:34:27
【问题描述】:

我正在使用 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);
    }

正面单元测试

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

还有负单元测试

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!
        });
    });

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

【问题讨论】:

    标签: angular unit-testing jasmine rxjs observable


    【解决方案1】:

    你的 observable 是一个值流,你可以这样做:

    正面:

    let invoked = 0;
    service.getPerson(30).subscribe(() => {
       invoked++;
    })
    expect(invoked).toEqual(2);
    

    否定:

    let invoked = 0;
    service.getPerson(55).subscribe(() => {
       invoked++;
    })
    expect(invoked).toEqual(0);
    

    【讨论】:

    • 我会将期望移动到订阅的完整回调中
    【解决方案2】:

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

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

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

    service.getPeople(minAge).subscribe(people => {
      fail('should not be called');
    });
    

    【讨论】:

    • 您可能是正确的,正面案例并没有真正测试您认为应该做的事情......但您可以想象这只是一个人为的例子。我的观点是肯定的情况会返回一些东西,而否定的情况不应该。在消极的情况下,我认为这确实是必要的。我的实际代码是从 websocket 观看数据流,所以我需要确保服务不会错误地响应通过管道传递的错误数据。
    • “失败”消息是我不知道的另一种选择,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多