加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Angular with Jasmine:beforeEach()中的异步和它()中的异步之间

发布时间:2020-12-17 07:16:39 所属栏目:安全 来源:网络整理
导读:我的目标是测试API调用,考虑延迟.我受到 this post的启发. 我设计了一个沙箱,其中模拟API需要1000毫秒来响应并更改全局变量结果的值.测试在500毫秒后和1500毫秒后检查值. 这是最后一次测试失败的代码: let result: number; const mockAPICall = (delay: num
我的目标是测试API调用,考虑延迟.我受到 this post的启发.

我设计了一个沙箱,其中模拟API需要1000毫秒来响应并更改全局变量结果的值.测试在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(),因为我将使用testBed和compileComponents.

解决方法

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

Writing test functions with done(),is more cumbersome than async and fakeAsync. But it is occasionally necessary. For example,you can’t call async or fakeAsync when testing code that involves the intervalTimer() or the RxJS delay() operator.

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

对于您的情况,您可以选择重构您的测试以不使用延迟操作符,或者您可以使用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
    );
})());

因为使用异步延迟时出现问题,Jasmine会提前“结束”测试 – 你没有看到失败,但你也看不到一些日志语句.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读