运行Angular2测试,调用setTimeout错误"无法在异步区域测试中使用setInterval"

Jua*_*des 5 unit-testing angular2-testing angular

我正在升级我们的Angular2应用程序以使用rc4,我开始在单元测试中出错:

无法在异步区域测试中使用setInterval

我的窗口小部件从其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);
    });
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

小智 2

我遇到了同样的问题。我可以使用 jasminedone参数来解决这个问题。

fit('lets you run timeouts', (done) => {
    async(() => {
        setTimeout(() => {
            expect(1).toBe(1);
            done();
        }, 10);
    });
});
Run Code Online (Sandbox Code Playgroud)