我有三个相互扩展的组件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引用此调用(请参阅下面的代码片段):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方法或CollectionElementComponent.prototype.ngOnInit = () => {}等方法中使用component.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
}
}最后,扩展CollectionElementComponent的TileComponent
export class TileComponent extends CollectionElementComponent implements OnInit {
constructor(
public selectableService: SelectableService,
) {
super(selectableService);
}
ngOnInit() {
super.ngOnInit();
// some other stuff
}
}任何帮助或提示都是非常感谢的,因为我真的没有想法…感谢您的支持!
发布于 2021-07-11 20:27:10
如果你使用的是ng-mocks,你也可以使用MockBuilder或MockProvider:
beforeEach(() => MockBuilder(
TileComponent,
[
CollectionElementComponent,
SelectableItemComponent,
SelectableService,
],
));
it('test', () => {
// mocking the prop of SelectableService
const selectedItems$ = new EventEmitter();
MockInstance(
SelectableService,
'onDeselectAllSelectedItems',
selectedItems$,
);
const fixture = MockRender(TileComponent);
// should work properly now
});https://stackoverflow.com/questions/60775547
复制相似问题