我在ngOnInit函数内部有一个带有setTimeOut函数的组件。为此,我要使用tick和fakeAsync来编写单元测试用例,以快速转发setTimeOut。但是,它没有被执行,因此又没有调用其他函数closeAlert()。
组件代码:
export class BannerComponent implements OnInit {
@Input()errorData: any;
@Input()callback: any;
@Input()autoHide: boolean;
constructor() { }
ngOnInit() {
if (this.autoHide) {
setTimeout
(() => {
this.closeAlert();
}, 500);
}
}
closeAlert() {
this.errorData = null;
if (this.callback) {
this.callback();
}
};
}
规范文件:
describe('BannerComponent', () => {
let component: BannerComponent;
let fixture: ComponentFixture<BannerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BannerComponent ]
})
.compileComponents();
}));
beforeEach(async() => {
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
component.ngOnInit();
fixture.detectChanges();
});
it("banner should hide after 500ms", fakeAsync(() => {
component.errorData = {
_statusMessage: "New alert banner",
_statusCode: '200',
};
component.callback = null;;
component.autoHide = true;
tick(600);
fixture.detectChanges()
fixture.whenStable().then(() => {
let banner = fixture.debugElement.query(By.css('.success'));
expect(banner).toBe(null)
})
}));
});
HTML代码:
<div class="success">
<p>{{errorData._statusMessage}}</p>
</div>
答案 0 :(得分:1)
我在代码中看到了几个问题。
component.ngOnInit()
中设置有效数据之前,您要同时调用fixture.detectChanges()
和component.errorData
(也将调用ngOnInit)。banner
与显示的html为空。因此,我将测试更改为看到component.closeAlert()
被调用,并且如果component.errorData
被重置为null,因为看来这是您真正想要测试的东西。为了测试这一点,我在component.closeAlert()
上进行了监视。component.closeAlert()
之后进行测试,然后在又一个滴答之后进行测试,来设置滴答声以准确显示何时向tick(499)
发出呼叫。工作StackBlitz。
代码:
beforeEach(async(() => { // slight correction of incorrect async wrapper ...
fixture = TestBed.createComponent(BannerComponent);
component = fixture.componentInstance;
// component.ngOnInit(); // <-- don't call this here, the data isn't set up yet ...
// fixture.detectChanges(); // ditto
}));
it("banner should hide after 500ms", fakeAsync(() => {
spyOn(component, 'closeAlert').and.callThrough(); // set up a spy so we can test later
component.errorData = {
_statusMessage: "New alert banner",
_statusCode: '200',
};
component.callback = null;;
component.autoHide = true;
fixture.detectChanges(); // <-- this will execute ngOnInit()
expect(component.errorData).not.toBeNull(); // <-- after ngOnInit, still NOT null
expect(component.closeAlert).not.toHaveBeenCalled();
tick(499); // <-- now let 499ms pass ...
expect(component.errorData).not.toBeNull(); // <-- after all that "fake" time, still NOT null
expect(component.closeAlert).not.toHaveBeenCalled();
tick(1); // <-- now tick for just 1 more millisecond ...
expect(component.errorData).toBeNull(); // <-- now this has become NULL
expect(component.closeAlert).toHaveBeenCalled(); // <-- and the method was called
// fixture.whenStable().then(() => {
// let banner = fixture.debugElement.query(By.css('.success'));
// expect(banner).toBe(null)
// });
}));
我希望这会有所帮助!