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

unit-testing – 运行Angular2测试,调用setTimeout错误,“不能在

发布时间:2020-12-17 17:39:46 所属栏目:安全 来源:网络整理
导读:我正在升级我们的Angular2应用程序以使用rc4,我开始在单元测试中出错: Cannot use setInterval from within an async zone test 我的窗口小部件从其ngOnInit方法请求数据,并在发出请求时发出加载指示符.我的模拟服务在1ms后返回一些数据. 这是一个暴露问题
我正在升级我们的Angular2应用程序以使用rc4,我开始在单元测试中出错:

Cannot use setInterval from within an async zone test

我的窗口小部件从其ngOnInit方法请求数据,并在发出请求时发出加载指示符.我的模拟服务在1ms后返回一些数据.

这是一个暴露问题的简化版本

import { inject,async,TestComponentBuilder,ComponentFixture} from '@angular/core/testing';
import {Http,Headers,RequestOptions,Response,HTTP_PROVIDERS} from '@angular/http';
import {provide,Component} from '@angular/core';

import {Observable} from "rxjs/Rx";

class MyService {
    constructor(private _http: Http) {}
    getData() {
        return this._http.get('/some/rule').map(resp => resp.text());
    }
}

@Component({
    template: `<div>
      <div class="loader" *ngIf="_isLoading">Loading</div>
      <div class="data" *ngIf="_data">{{_data}}</div>
    </div>`
})
class FakeComponent {
    private _isLoading: boolean = false;
    private _data: string = '';

    constructor(private _service: MyService) {}

    ngOnInit() {
        this._isLoading = true;
        this._service.getData().subscribe(data => {
            this._isLoading = false;
            this._data = data;
        });
    }
}

describe('FakeComponent',() => {
    var service = new MyService(null);
    var _fixture:ComponentFixture<FakeComponent>;

    beforeEach(async(inject([TestComponentBuilder],(tcb:TestComponentBuilder) => {
        return tcb
            .overrideProviders(FakeComponent,[
                HTTP_PROVIDERS,provide(MyService,{useValue: service}),])
            .createAsync(FakeComponent)
            .then((fixture:ComponentFixture<FakeComponent>) => {
                _fixture = fixture;
            });
    })));

    it('Shows loading while fetching data',(cb) => {
        // Make the call to getData take one ms so we can verify its state while the request is pending
        // Error occurs here,when the widget is initialized and sends out an XHR
        spyOn(service,'getData').and.returnValue(Observable.of('value').delay(1));
        _fixture.detectChanges();
        expect(_fixture.nativeElement.querySelector('.loader')).toBeTruthy();
        // Wait a few ms,should not be loading
        // This doesn't seem to be the problem
        setTimeout(() => {
            _fixture.detectChanges();
            expect(_fixture.nativeElement.querySelector('.loader')).toBeFalsy();
            cb();
        },10);
    });
});

这在Angular2 rc1中运行正常,它会在rc4中引发错误,有什么建议吗?

此外,如果直接从测试本身使用setTimeout,则没有错误

fit('lets you run timeouts',async(() => {
            setTimeout(() => {
                expect(1).toBe(1);
            },10);
        }));

解决方法

我发现由于某种原因,你不能在测试中使用用Observable.of(任何).delay()创建的promise.

我的解决方案是自己实现这条线,考虑到问题中发布的另一个例子确实有效,这几乎是有意义的.

// This is what we should be doing,but somehow,it isn't working.
// return Observable.of(result).delay(0));
function createDelayedObservable <T>(result:any,time:number = 0):Observable<T> {
    return new Observable<T>(observer => {
        setTimeout(() =>  observer.next(result),time);
    });
}

但是,我仍然不明白为什么下面没有失败,所以我不接受我自己的答案,希望对区域有深刻理解的人能告诉我发生了什么.

it('should be able to use delay in tests',(cb) => {
    var obs = Observable.of(1).delay(0);
    obs.subscribe(val => {
        expect(val).toBe(1);
        cb()
    });
});

(编辑:李大同)

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

    推荐文章
      热点阅读