【问题标题】:Angular with Jasmine: is there a conflict between async in beforeEach() and async in it()?Angular 与 Jasmine:beforeEach() 中的异步和 it() 中的异步之间是否存在冲突?
【发布时间】:2018-08-10 16:47:44
【问题描述】:

我的目标是测试 API 调用,同时考虑延迟。我的灵感来自this post

我设计了一个沙箱,其中一个模拟 API 需要 1000 毫秒来响应和更改全局变量 result 的值。测试在 500 毫秒和 1500 毫秒后检查值。

这是最后一次测试应该失败的代码:

    let result: number;
    
    const mockAPICall = (delay: number): Observable<number> => {
        console.log('API called');
        return Observable.of(5).delay(delay);
    };
    
    beforeEach(() => {
        console.log('before each');
    });
    
    it('time test', async(() => {
        result = 0;
        const delay = 1000;
        console.log('start');

        mockAPICall(delay).subscribe((apiResult: number) => {
            console.log('obs done');
            result = apiResult;
        });

        console.log('first check');
        expect(result).toEqual(0);

        setTimeout(() => {
                console.log('second check');
                expect(result).toEqual(0);
            }, 500
        );

        setTimeout(() => {
                console.log('third check');
                expect(result).toEqual(0);
            }, 1500
        );
    }));

最后一次测试确实失败了,我在日志中得到了这个:

before each
API called
first check
second check
obs done
third check

现在如果我在beforeEach() 中放置一个async()

    beforeEach(async(() => {
        console.log('async before each');
    }));

,测试通过了,我只在日志中得到这个:

async before each
API called
first check

我没想到。为什么会有这种行为?幕后发生了什么?

注意:在以后的测试中,我将在beforeEach() 中使用这个async(),因为我将使用testBedcompileComponents

【问题讨论】:

    标签: angular asynchronous jasmine


    【解决方案1】:

    您的问题源于在测试期间使用区域的不幸边缘情况,并且在 Angular 文档here 中进行了概述。

    done() 编写测试函数,比asyncfakeAsync 更麻烦。但偶尔也有必要。例如,在测试涉及intervalTimer() 或RxJS delay() 运算符的代码时,您不能调用asyncfakeAsync

    这与rxjs 中定时器的实现有关,并且有很多很好的材料可以帮助您使用TestScheduler 来测试使用其中一些运算符(如delay)的rxjs 代码。

    对于您的情况,您可以选择重构您的测试以不使用 delay 运算符,或者您可以使用 Jasmine 提供的 done()

    let result: number;
    
    const mockAPICall = (delay: number): Observable<number> => {
        console.log('API called');
        return Observable.of(0).delay(delay); // changed from 5 -> 0, to make tests pass
    };
    
    beforeEach(async(() => {
        console.log('async before each');
    }));
    
    it('time test', done => async(() => {
        result = 0;
        const delay = 1000;
        console.log('start');
    
        mockAPICall(delay).subscribe((apiResult: number) => {
            console.log('obs done');
            result = apiResult;
        });
    
        console.log('first check');
        expect(result).toEqual(0);
    
        setTimeout(() => {
                console.log('second check');
                expect(result).toEqual(0);
            }, 500
        );
    
        setTimeout(() => {
                console.log('third check');
                expect(result).toEqual(0);
                done(); // indicate that the test is complete
            }, 1500
        );
    })());
    

    因为使用 delayasync 时出现问题,Jasmine 提前“结束”测试 - 您看不到失败,但也看不到某些日志记录语句。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-26
      • 2014-10-24
      • 2021-10-16
      • 2019-08-31
      • 2014-09-03
      • 2015-08-03
      • 2011-05-24
      • 1970-01-01
      相关资源
      最近更新 更多