【问题标题】:Test that an Angular observable emits a value or sequence测试 Angular 可观察对象是否发出值或序列
【发布时间】:2019-05-18 22:41:17
【问题描述】:

我有一个服务,它创建了一个发出值的可观察对象,并且相对容易测试发出的值是否符合预期。

例如:

describe('service', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({providers: [MyService]});
    });

    it('should emit true', async(() => {
        const service = TestBed.get(MyService);
        service.values$.subscribe((value) => expect(value).toBeTruthy());
    }));
});

上面的方法可以测试期望值,但它只有在服务实际发出值时才有效。如果您遇到服务无法发出值的极端情况,那么测试本身实际上会通过并且 Jasmine 会记录警告消息“SPEC HAS NO EXPECTATIONS should be created”。

我在 Google 上搜索了一段时间,试图弄清楚如何将此案例视为错误并想出了这种方法。

    it('should emit true', async(() => {
        const service = TestBed.get(MyService);
        let value;
        service.values$.subscribe((v) => value = v);
        expect(value).toBeTruthy();
    }));

以上内容仅适用于同步 observables,对我来说就像代码异味。其他开发人员会看到这一点并认为这是一个低质量的测试。

所以在考虑了几天之后。我想过使用takeUntil() 来强制observable 完成,然后测试预期的结果。

例如:

describe('service', () => {
    let finished: Subject<void>;

    beforeEach(() => {
        TestBed.configureTestingModule({providers: [MyService]});
        finished = new Subject();
    });

    afterEach(() => {
        finished.next();
        finished.complete();
    });

    it('should emit true', async(() => {
        const service = TestBed.get(MyService);
        let value;
        service.changes$
            .pipe(
                takeUntil(finished),
                finalize(() => expect(value).toBeTruthy())
            )
            .subscribe((v) => value = v);
    }));
});

在上面的例子中,值被存储在一个局部变量中,然后在 observable 完成时检查预期的结果。我通过使用afterEach() 和takeUntil() 来强制完成。

问题:

我的方法是否有任何副作用,如果有的话,执行此类测试的更 Angular/Jasmine 方式是什么。我担心您不应该在 afterEach() 生命周期调用期间执行 expect 断言。

【问题讨论】:

    标签: javascript angular jasmine rxjs observable


    【解决方案1】:

    这对我来说似乎太过分了。

    Jasmine 在它的测试中提供了一个回调,你可以简单地使用它吗?

    it('should X', doneCallback => {
      myObs.subscribe(res => {
        expect(x).toBe(y);
        doneCallback();
      });
    });
    

    如果未调用回调,则测试失败并出现超时异常(意味着在此失败后将不再运行测试)

    【讨论】:

    • Overkill 是我的中间名。谢谢,我会试试这个。我读过的所有地方都说您应该使用 Angular async 函数。那有什么不同?
    • 对于初学者来说,这是有偏见的,因为您不必在测试中使用测试平台或任何角度特征。例如,我们有很重的组件,我们对代码进行单元测试,但接口是通过 E2E 测试来测试的(减少了测试时间很多)。 Angular async(不是 fakeAsync BTW 吗?)只是解决了代码中的待处理操作,它并没有做更多的事情。我从未使用过它,也从未遇到过我的异步代码处于待处理状态的测试问题。所以这真的是基于意见,但对我来说async 没用!
    • facepalm。我刚刚阅读了it() 的函数签名,它支持设置超时值。我的印象是 Jasmine 纯粹是同步的。
    • Sh*t 发生了,至少你知道为你的测试输入的代码要少得多:)
    猜你喜欢
    • 2020-04-08
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    相关资源
    最近更新 更多