单元测试不适用于扩展基数 class 的 class
Unit test not behaving for a class that extends a base class
我正在努力测试一个组件 class,它扩展了另一个抽象 class。
两个class如下:
export abstract class BaseListComponent {
constructor(
protected someImportantService: SomeImportantService
){
}
handleListInitialization() {
// Do lots of things
this.doOtherStuff();
}
/**
* @abstract doOtherStuff Function
*/
protected abstract doOtherStuff( );
}
export class MyListComponent extends BaseListComponent {
constructor(
someImportantService: SomeImportantService,
private listService: ListService
) {
super( someImportantService );
}
doStuff = () => {
this.handleListInitialization();
}
doOtherStuff(){
this.listService.getThings().then(() => {
// process response...
})
}
}
我正在尝试测试在 MyListComponent
中调用 doStuff
时会导致在 doOtherStuff
方法中调用 listService.getThings()
。
describe('When calling doStuff()', () => {
it('should call getThings from the ListService instance', ( ) => {
spyOn(component.listService, 'getThings').and.returnValue(Promise.then({foo: 'bar'}));
component.doStuff();
expect(component.listService.getThings).toHaveBeenCalled();
});
});
执行此测试时,我收到一条错误消息,指出从未调用过间谍程序,但奇怪的是,我的覆盖率报告显示我的 doOtherStuff()
实现的行已完全覆盖。
如果我在我的测试套件中改为调用 doOtherStuff()
,那么测试就会顺利通过。
我不明白为什么会这样,我想知道我的抽象基础 class 是否以某种方式错误地实现了,尽管当 运行 应用程序正常工作时期待。
这可能是什么问题?
您需要 post 编写更多代码来创建 component
,也许它被模拟了,在这种情况下,失败是意料之中的。 类 及其继承看起来不错,在描述的情况下应该可以通过测试。
问题是当 doOtherStuff
被调用时,就在那一刻你是 subscribing/attending 承诺。
如果你想接收this.listService.getThings()
的值,你需要等到下一个时钟被执行。
要处理此问题,您可以使用 Angular 中的 fakeAysnc and tick。
我认为我们可以像这样使用 fakeAsync 重写您的测试:
describe('When calling doStuff()',() => {
it('should call getThings from the ListService instance', fakeAsync(() => {
component.doStuff();
tick();
fixture.detectChanges();
spyOn(component.listService, 'getThings').and.returnValue(Promise.then({foo: 'bar'}));
tick();
fixture.detectChanges();
expect(component.listService.getThings).toHaveBeenCalled();
}));
});
它应该可以用。
我正在努力测试一个组件 class,它扩展了另一个抽象 class。
两个class如下:
export abstract class BaseListComponent {
constructor(
protected someImportantService: SomeImportantService
){
}
handleListInitialization() {
// Do lots of things
this.doOtherStuff();
}
/**
* @abstract doOtherStuff Function
*/
protected abstract doOtherStuff( );
}
export class MyListComponent extends BaseListComponent {
constructor(
someImportantService: SomeImportantService,
private listService: ListService
) {
super( someImportantService );
}
doStuff = () => {
this.handleListInitialization();
}
doOtherStuff(){
this.listService.getThings().then(() => {
// process response...
})
}
}
我正在尝试测试在 MyListComponent
中调用 doStuff
时会导致在 doOtherStuff
方法中调用 listService.getThings()
。
describe('When calling doStuff()', () => {
it('should call getThings from the ListService instance', ( ) => {
spyOn(component.listService, 'getThings').and.returnValue(Promise.then({foo: 'bar'}));
component.doStuff();
expect(component.listService.getThings).toHaveBeenCalled();
});
});
执行此测试时,我收到一条错误消息,指出从未调用过间谍程序,但奇怪的是,我的覆盖率报告显示我的 doOtherStuff()
实现的行已完全覆盖。
如果我在我的测试套件中改为调用 doOtherStuff()
,那么测试就会顺利通过。
我不明白为什么会这样,我想知道我的抽象基础 class 是否以某种方式错误地实现了,尽管当 运行 应用程序正常工作时期待。
这可能是什么问题?
您需要 post 编写更多代码来创建 component
,也许它被模拟了,在这种情况下,失败是意料之中的。 类 及其继承看起来不错,在描述的情况下应该可以通过测试。
问题是当 doOtherStuff
被调用时,就在那一刻你是 subscribing/attending 承诺。
如果你想接收this.listService.getThings()
的值,你需要等到下一个时钟被执行。
要处理此问题,您可以使用 Angular 中的 fakeAysnc and tick。
我认为我们可以像这样使用 fakeAsync 重写您的测试:
describe('When calling doStuff()',() => {
it('should call getThings from the ListService instance', fakeAsync(() => {
component.doStuff();
tick();
fixture.detectChanges();
spyOn(component.listService, 'getThings').and.returnValue(Promise.then({foo: 'bar'}));
tick();
fixture.detectChanges();
expect(component.listService.getThings).toHaveBeenCalled();
}));
});
它应该可以用。