[英]Testing Angular component extending an abstract class
I have this setup for a number of components:我为许多组件设置了此设置:
@Directive()
export abstract class BaseComponent implements OnInit {
@Select(PortalState.portal) public portalState: Observable<PortalModel>;
public portal: PortalModel;
protected ngUnsubscribe: Subject<void> = new Subject();
constructor(
protected someService: SomeService,
protected route: ActivatedRoute
){
}
public ngOnInit(): void {
this.route.params
.pipe(
filter(res => !!res),
tap(res => this.id = res['id']),
switchMap(() => this.portalState),
takeUntil(this.ngUnsubscribe)
)
.subscribe(res => {
this.portal = res;
this.afterInit();
});
}
public ngOnDestroy(): void {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
public abstract afterInit(): void
}
and then in every component which extends this base class:然后在扩展此基础 class 的每个组件中:
@Component({...})
export class SomeComponent extends BaseComponent {
public specificVar: any;
constructor(
protected someService: SomeService,
protected route: ActivatedRoute
){
super(someService, route);
}
public afterInit(): void {
/** do component specific stuff */
this.specificVar = 'something';
}
}
Now it works fine, however when testing, the abstract component's ngOnInit seems to be not called at all rendering (in this example) this.specific
variable as undefined.现在它工作正常,但是在测试时,似乎根本没有调用抽象组件的 ngOnInit 渲染(在本例中)
this.specific
变量为未定义。
the spec file looks quite traditional规范文件看起来很传统
let store: Store; /** Ngxs store */
const mockPortalModel: PortalModel = {id: 1};
beforeEach(async () => {
TestBed.configureTestingModule(/** providers and usual setup */);
store = TestBed.inject(Store);
store.reset({
portalState: mockPortalModel
});
jest.spyOn(store, 'dispatch');
jest.spyOn(store, 'select');
});
beforeEach(() => {
fixture = TestBed.createComponent(SomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
Any ideas why ngOnInit
and subsequently afterInit
are not being called?有什么想法为什么不调用
ngOnInit
和随后的afterInit
吗?
You have to write below function in your SomeComponent
so that it will run your BaseComponent
's ngOnInit
method after SomeComponent
's ngOnInit
method.您必须在 SomeComponent 的
SomeComponent
,以便它在SomeComponent
的ngOnInit
方法之后运行您的BaseComponent
的ngOnInit
方法。
ngOnInit() {
super.ngOnInit();
}
The problem was in this.route.params
which had to be mocked, so the subscription could fire.问题出在必须模拟的
this.route.params
中,因此订阅可能会触发。 So mocking activated route has solved the issue:所以mocking激活路由解决了这个问题:
const mockActivatedRoute = {
snapshot: {}, // needs to be there to avoid _lastPathIndex error
params: of({id: 123})
}
/** ... */
providers: [
{provide: ActivatedRoute, useValue: mockActivatedRoute }
]
had ensured that the subscription goes through (see that filter(res => !!res)
- it stopped right there).已确保订阅通过(请参阅
filter(res => !!res)
- 它就停在那里)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.