测试未捕获的错误:macroTask'setInterval':无法转换为'running',期望状态为'scheduled',为'notScheduled'

Sil*_*Sil 7 google-chrome phantomjs karma-jasmine angular

我正在使用Angular版本“ 4.2.2”,Angular Cli版本“ 1.1.1”和zone.js 0.8.12。我的一些曾经在Chrome和PhanthomJS中都可以使用的单元测试现在由于以下错误而失败:

错误未捕获错误:macroTask'setInterval':无法转换为'running',期望状态为'scheduled',为'notScheduled'。

任何人都曾经见过这些错误,并且知道如何解决这些错误?

Oys*_*ker 3

好吧,经过一些研究,我发现大多数人(甚至是 Angular 的人)都说,使用asyncfakeAsync使用涉及intervalTimer(常见于 Observable 方法)的代码根本无法完成。

我在这个链接中找到了这个

例如,我正在使用 Angular2 文档中详细说明的fakeAsynctick技术测试可观察的方法,并遇到了此错误。(见下面的测试)

it('#findCaseMasks should show error if error is returned from service', fakeAsync(() => {
        component.searchCriteria = new CaseMaskModel(1, 1);
        caseMaskServiceSpy = spyOn(service, 'findCaseMasks').and.returnValue(Observable.throw('error occured', Scheduler.async));
        component.findCaseMasks();
        expect(component.error).toBeNull;
        tick();
        fixture.detectChanges();
        expect(component.error).toEqual('Something went wrong. Please contact helpdesk if the issue persists.');
    }));
Run Code Online (Sandbox Code Playgroud)

上面的测试已更改为您在下面看到的内容,并且测试开始正常工作。

it('#findCaseMasks should show error if error is returned from service', (done) => {
        component.searchCriteria = new CaseMaskModel(1, 1);
        caseMaskServiceSpy = spyOn(service, 'findCaseMasks').and.returnValue(Observable.throw('error occured', Scheduler.async));
        component.findCaseMasks();
        expect(component.error).toBeNull;
        caseMaskServiceSpy.calls.mostRecent().returnValue.subscribe(
            () => { //success
                //put code here if testing for success
            },
            err => { //error
                //put code here if testing for error

                fixture.detectChanges();
                expect(component.error).toEqual('Something went wrong. Please contact helpdesk if the issue persists.');
                done();
            });
    });
Run Code Online (Sandbox Code Playgroud)

因此,基本上,您必须监视使用“jasmine.Spy”注入组件的服务,然后订阅其最近的调用。然后您就会熟悉订阅语法,以便检查错误并检查是否成功。

作为参考,监视注入服务的步骤如下:

  1. 在方法的顶部添加一个describe与您要监视的服务类型相同的变量,即。let casemaskService: CaseMaskService;
  2. 在方法顶部创建一个describe类型为 的变量jasmine.Spy,即let casemaskServiceSpy: jasmine.Spy;
  3. 将服务变量设置为等于fixture相同类型的注入服务,即casemaskService = fixture.debugElement.injector.get(CaseMaskService);。(我通常在同步beforeEach方法中这样做)
  4. 在任何规范期间的任何时候,只需将spy变量设置为等于spyOn实例并告诉它返回什么,即caseMaskSpy = spyOn(casemaskService, 'updateCaseMask').and.returnValue(Observable.of(${mockCaseMask.caseMaskingId} 已更新!, Scheduler.async));

那时您可以使用我上面粘贴的代码并且应该可以正常使用。