cel*_*ade 3 javascript unit-testing angular
我正在尝试对组件内部的功能进行单元测试,此功能是根据初始条件从ngOnInit调用的:
ngOnInit() {
if (this.list.length === 0) {
return this.loadData();
}
return this.isLoading = false;
}
// I'm calling here because it could also be called from button on the UI
loadData() {
this.apiService.apiGet().subscribe((response) => {
// handle data
return this.isLoading = false;
}, (error) => {
// handle error
return this.isLoading = false;
})
}
Run Code Online (Sandbox Code Playgroud)
但是,除非我在测试中手动调用该函数,否则我无法对其进行测试。这是我的测试代码:
// THIS CODE WORKS
it('should be false after calling loadData()', async(() => {
component.loadData();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.isLoading).toBeFalsy();
});
}));
// THIS CODE DOESN'T work
it('should be false after calling loadData()', async(() => {
spyOn(component,'loadData').and.returnValue({code:'success'});
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.isLoading).toBeFalsy();
});
}));
Run Code Online (Sandbox Code Playgroud)
这也是我用来模拟apiGet函数的一段代码:
apiGet() {
return Observable.of({ data: 'success' });
}
Run Code Online (Sandbox Code Playgroud)
但是我知道正在执行ngOnInit并且正在调用该函数,因为此测试通过了:
it('should be called if list array is empty', () => {
spyOn(component,'loadData').and.returnValue({code:'success'});
fixture.detectChanges();
expect(component.loadData).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?为什么测试失败没有达到最终的承诺?
此模拟方法未设置isLoading,但它返回的值与此处无关:
spyOn(component,'loadData').and.returnValue({code:'success'});
Run Code Online (Sandbox Code Playgroud)
因此,它的行为明显不同于实际方法。如果这意味着使这个期望为假,那就是:
expect(component.isLoading).toBeFalsy();
Run Code Online (Sandbox Code Playgroud)
测试此内容的正确方法是逐行在几个独立的规范中对此进行测试:
// ngOnInit test
spyOn(component, 'loadData');
this.list.length = 0;
fixture.detectChanges();
expect(component.loadData).toHaveBeenCalled();
expect(component.isLoading).toBe(true);
// ngOnInit test
spyOn(component, 'loadData');
this.list.length = 1;
fixture.detectChanges();
expect(component.loadData).not.toHaveBeenCalled();
expect(component.isLoading).toBe(false);
// loadData test
const apiServiceMock = {
apiGet: jasmine.createSpy().and.returnValue(Observable.of(...))
};
this.apiService = apiServiceMock; // or mock via DI
spyOn(component, 'loadData').andCallThrough();
fixture.detectChanges();
// OR
// component.loadData()
expect(component.loadData).toHaveBeenCalled();
expect(apiServiceMock.apiGet).toHaveBeenCalled()
expect(component.isLoading).toBe(false);
// loadData test
const apiServiceMock = {
apiGet: jasmine.createSpy().and.returnValue(Observable.throw(...))
};
// the rest is same
// loadData test
const apiServiceMock = {
apiGet: jasmine.createSpy().and.returnValue(Observable.empty())
};
fixture.detectChanges();
expect(component.loadData).toHaveBeenCalled();
expect(apiServiceMock.apiGet).toHaveBeenCalled()
expect(component.isLoading).toBe(true);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7759 次 |
| 最近记录: |