我正在使用 Angular2.0.1 并试图围绕一个带有一些异步任务的角度组件编写单元测试。我会说,这是一件相当普遍的事情。甚至他们最新的测试示例也包括此类异步测试(请参阅此处)。
但是,我自己的测试永远不会成功,总是以消息失败
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
长话短说,我花了几个小时来查明问题的实际根源。我正在使用库 angular2-moment,并且在那里我使用了一个名为 amTimeAgo 的管道。此管道包含一个 window.setTimeout(...),它永远不会被删除。如果我删除了 amTimeAgo 管道,测试会成功,否则会失败。
这是一些非常简单的代码来重现该问题:
测试组件.html:
{{someDate | amTimeAgo}}
测试组件.ts:
import { Component } from "@angular/core";
import * as moment from "moment";
@Component({
moduleId: module.id,
templateUrl: "testcomponent.html",
providers: [],
})
export class TestComponent{
someDate = moment();
constructor() {
}
}
测试模块.ts
import { NgModule } from "@angular/core";
import {MomentModule} from 'angular2-moment';
import { TestComponent } from './testcomponent';
@NgModule({
imports: [
MomentModule,
],
declarations: [
TestComponent,
]
})
export class TestModule {
}
testcomponent.spec.ts:
import { async, TestBed, ComponentFixture } from "@angular/core/testing";
import { TestComponent } from './testcomponent';
import { TestModule } from './testmodule';
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
function createComponent() {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
return Promise.resolve();
}
describe("TestComponent", () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
TestModule],
}).compileComponents();
}));
it('should load the TestComponent', async(() => {
createComponent().then(() => {
expect(component).not.toBe(null);
});
}));
});
有谁知道如何成功测试这个?我可以以某种方式杀死 afterEach 中的所有“剩余”超时吗?或者我可以以某种方式重置异步代码运行的区域以摆脱这个问题吗?
有没有其他人遇到过这个或知道如何成功测试这个?任何提示将不胜感激。
更新:
@peeskillet 暗示使用 的解决方案后fixture.destroy()
,我开始在我的实际测试中尝试了这个(这里的示例只是重现问题所需的最少代码)。实际的测试包含嵌套的 Promise,否则我不需要async
anddetectChanges
方法。
虽然 destroy 建议很棒并且有助于解决简单测试中的问题,但我的实际测试包含以下语句以确保嵌套的 Promise 得到正确解决:
it('should check values after nested promises resolved', async(() => {
createComponent().then(() => {
fixture.whenStable().then(() => {
component.selectedToolAssemblyId = "2ABC100035";
expect(component.selectedToolAssembly).toBeDefined();
expect(component.selectedToolAssembly.id).toBe("2ABC100035");
fixture.destroy();
});
fixture.detectChanges();
});
}));
问题是,在页面中使用 amTimeAgo 管道时,fixture.whenStable()
promise 永远不会得到解决,因此我的断言代码永远不会执行,并且测试仍然会以相同的超时失败。
因此,即使破坏建议适用于给定的简化测试,它也不能让我修复实际测试。
谢谢
本