【发布时间】:2020-03-20 13:52:56
【问题描述】:
我有三个相互扩展的组件 TileComponent -> CollectionElementComponent -> SelectableItemComponent。现在,我正在尝试使用 Jasmine 3.4.0 和 Angular 8 为 TileComponent 类编写一些单元测试。但是,测试(应该创建组件)失败,因为模拟的 selectableService 没有正确注入扩展扩展组件:
Failed: Uncaught (in promise): TypeError: Cannot read property 'pipe' of undefined
TypeError: Cannot read property 'pipe' of undefined
at TileComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/shared/components/selectable/selectable-item.component.ts:26:14)
at TileComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/collection/view/elements/collection-element/collection-element.component.ts:32:15)
at TileComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/collection/view/elements/tile/tile.component.ts:65:15)
selectable-item.component.ts:26:14 指代此调用(另请参阅下面的代码 sn-p):this.selectableService.onDeselectAllSelectedItems.pipe(...)
我这样初始化测试组件:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
TileComponent,
],
providers: [
{ provide: SelectableService, useClass: MockSelectableService },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
.compileComponents()
.then(() => {
fixture = TestBed.createComponent(TileComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
}));
it('should create component', () => {
expect(component).toBeTruthy();
});
});
...
@Injectable()
class MockSelectableService {
onDeselectAllSelectedItems = new EventEmitter<void>();
}
这种将服务注入组件的方式适用于其他组件测试,所以我不完全确定它为什么会在这里失败。我已经尝试了几乎所有东西,在两个父组件的声明中使用ng-mocks 和MockComponent(),尝试模拟父母并使用{ provide: ComponentName, useClass: MockComponentName} 注入它们。还尝试在 beforeEach 方法中使用 component.ngOnInit = () => {} 或 CollectionElementComponent.prototype.ngOnInit = () => {} 等覆盖 ngOnInit 方法。所有这些都会导致相同的错误。
受影响的组件如下所示:
export class SelectableItemComponent implements OnInit {
constructor(
public selectableService: SelectableService
) { }
ngOnInit() {
this.selectableService.onDeselectAllSelectedItems
.pipe(takeUntil(this.componentDestroyed$))
.subscribe(this.deselectItem.bind(this));
}
}
这个类由 CollectionElementComponent 扩展:
export class CollectionElementComponent extends SelectableItemComponent implements OnInit {
constructor(
public selectableService: SelectableService,
) {
super(selectableService);
}
ngOnInit() {
super.ngOnInit();
// some other stuff
}
}
最后,TileComponent 扩展了 CollectionElementComponent
export class TileComponent extends CollectionElementComponent implements OnInit {
constructor(
public selectableService: SelectableService,
) {
super(selectableService);
}
ngOnInit() {
super.ngOnInit();
// some other stuff
}
}
非常感谢任何帮助或提示,因为我真的没有想法...... 感谢支持!
【问题讨论】:
-
错误提示
onDeselectAllSelectedItems未定义。这意味着selectableService已定义 并且依赖注入似乎有效。MockSelectableService是否有属性onDeselectAllSelectedItems? -
感谢@rveerd。是的,
MockSelectableService确实具有onDeselectAllSelectedItems属性(参见上面的代码)。我是从原SelectableService复制过来的,所以应该是一模一样的。 -
尝试调试测试以了解
this.selectableService是什么以及它具有哪些属性? -
无法真正让调试正常运行,但这是另一个问题。幸运的是,问题现在自己解决了,我不知道为什么。重新启动 VSCode,现在它可以工作了。无论如何感谢您的支持!
标签: angular jasmine karma-jasmine