ngOnDestroy 上的茉莉花测试失败
jasmine test on ngOnDestroy fails
我正在尝试使用 angular 中的 jasmine 编写测试 ngOnDestroy 并收到错误 Expected spy ngOnDestroy to have been called。
有人可以告诉我问题是什么
组件
export class DialogComponent implements AfterViewInit, OnDestroy {
private readonly _onClose = new Subject<any>();
public componentRef: ComponentRef<any>;
public childComponentType: Type<any>;
public onClose = this._onClose.asObservable();
// add this:
@ViewChild(InsertionDirective, { static: false })
insertionPoint: InsertionDirective;
constructor(public componentFactoryResolver: ComponentFactoryResolver,
public cd: ChangeDetectorRef,
public dialog: DialogRef) {
}
ngAfterViewInit() {
this.loadChildComponent(this.childComponentType);
this.cd.detectChanges();
}
ngOnDestroy() {
if (this.componentRef) {
this.componentRef.destroy();
}
}
loadChildComponent(componentType: Type<any>) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
const viewContainerRef = this.insertionPoint.viewContainerRef;
viewContainerRef.clear();
this.componentRef = viewContainerRef.createComponent(componentFactory);
}
closeModal() {
this.dialog.close();
}
}
测试组件
describe('DialogComponent', () => {
let component: DialogComponent;
let fixture: ComponentFixture<DialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [SharedModule, DialogModule],
providers: [DialogConfig, DialogRef ]
})
.overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [DialogComponent, ExampleComponent] } })
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DialogComponent);
component = fixture.componentInstance;
component.childComponentType = ExampleComponent;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
fit('should call ngOnDestroy ', () => {
spyOn(component, 'ngOnDestroy').and.callThrough();
expect(component.ngOnDestroy).toHaveBeenCalled();
});
});
ComponentRef 定义
export declare abstract class ComponentRef<C> {
/**
* The host or anchor [element](guide/glossary#element) for this component instance.
*/
abstract readonly location: ElementRef;
/**
* The [dependency injector](guide/glossary#injector) for this component instance.
*/
abstract readonly injector: Injector;
/**
* This component instance.
*/
abstract readonly instance: C;
/**
* The [host view](guide/glossary#view-tree) defined by the template
* for this component instance.
*/
abstract readonly hostView: ViewRef;
/**
* The change detector for this component instance.
*/
abstract readonly changeDetectorRef: ChangeDetectorRef;
/**
* The type of this component (as created by a `ComponentFactory` class).
*/
abstract readonly componentType: Type<any>;
/**
* Destroys the component instance and all of the data structures associated with it.
*/
abstract destroy(): void;
/**
* A lifecycle hook that provides additional developer-defined cleanup
* functionality for the component.
* @param callback A handler function that cleans up developer-defined data
* associated with this component. Called when the `destroy()` method is invoked.
*/
abstract onDestroy(callback: Function): void;
}
没有事件触发函数 ngOnDestroy 的调用。您应该做的是在您的测试中调用 ngOnDestroy,然后检查它是否执行所需的功能。
fit('should call ngOnDestroy ', () => {
let childFixture: ComponentFixture<ExampleComponent>;
component.componentRef = childFixture.componentRef;
spyOn(component.componentRef, 'destroy').and.callThrough();
component.ngOnDestroy();
expect(component.componentRef.destroy).toHaveBeenCalled();
});
我正在尝试使用 angular 中的 jasmine 编写测试 ngOnDestroy 并收到错误 Expected spy ngOnDestroy to have been called。 有人可以告诉我问题是什么
组件
export class DialogComponent implements AfterViewInit, OnDestroy {
private readonly _onClose = new Subject<any>();
public componentRef: ComponentRef<any>;
public childComponentType: Type<any>;
public onClose = this._onClose.asObservable();
// add this:
@ViewChild(InsertionDirective, { static: false })
insertionPoint: InsertionDirective;
constructor(public componentFactoryResolver: ComponentFactoryResolver,
public cd: ChangeDetectorRef,
public dialog: DialogRef) {
}
ngAfterViewInit() {
this.loadChildComponent(this.childComponentType);
this.cd.detectChanges();
}
ngOnDestroy() {
if (this.componentRef) {
this.componentRef.destroy();
}
}
loadChildComponent(componentType: Type<any>) {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(componentType);
const viewContainerRef = this.insertionPoint.viewContainerRef;
viewContainerRef.clear();
this.componentRef = viewContainerRef.createComponent(componentFactory);
}
closeModal() {
this.dialog.close();
}
}
测试组件
describe('DialogComponent', () => {
let component: DialogComponent;
let fixture: ComponentFixture<DialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [SharedModule, DialogModule],
providers: [DialogConfig, DialogRef ]
})
.overrideModule(BrowserDynamicTestingModule, { set: { entryComponents: [DialogComponent, ExampleComponent] } })
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DialogComponent);
component = fixture.componentInstance;
component.childComponentType = ExampleComponent;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
fit('should call ngOnDestroy ', () => {
spyOn(component, 'ngOnDestroy').and.callThrough();
expect(component.ngOnDestroy).toHaveBeenCalled();
});
});
ComponentRef 定义
export declare abstract class ComponentRef<C> {
/**
* The host or anchor [element](guide/glossary#element) for this component instance.
*/
abstract readonly location: ElementRef;
/**
* The [dependency injector](guide/glossary#injector) for this component instance.
*/
abstract readonly injector: Injector;
/**
* This component instance.
*/
abstract readonly instance: C;
/**
* The [host view](guide/glossary#view-tree) defined by the template
* for this component instance.
*/
abstract readonly hostView: ViewRef;
/**
* The change detector for this component instance.
*/
abstract readonly changeDetectorRef: ChangeDetectorRef;
/**
* The type of this component (as created by a `ComponentFactory` class).
*/
abstract readonly componentType: Type<any>;
/**
* Destroys the component instance and all of the data structures associated with it.
*/
abstract destroy(): void;
/**
* A lifecycle hook that provides additional developer-defined cleanup
* functionality for the component.
* @param callback A handler function that cleans up developer-defined data
* associated with this component. Called when the `destroy()` method is invoked.
*/
abstract onDestroy(callback: Function): void;
}
没有事件触发函数 ngOnDestroy 的调用。您应该做的是在您的测试中调用 ngOnDestroy,然后检查它是否执行所需的功能。
fit('should call ngOnDestroy ', () => {
let childFixture: ComponentFixture<ExampleComponent>;
component.componentRef = childFixture.componentRef;
spyOn(component.componentRef, 'destroy').and.callThrough();
component.ngOnDestroy();
expect(component.componentRef.destroy).toHaveBeenCalled();
});