'jasmine window.location.reload in ngOnDestroy
public ngOnDestroy(): void { window.location.reload(); }
How can I unit test this? All answers I found didn't work or only worked when the test was the only one executed. It looks like jasmine is inherently calling ngOnDestroy() outside of a test suite scope. Mocking ngOnDestroy() and writing a console.log into the real thing also always resulted in a console output.
specs:
- karma-jasmine: 4.0.2
- jasmine-core: 4.0.0
- angular: 12
For completion, I tried the following:
(also checked every possibility in beforeAll(), afterEach() and afterAll())
mock ngOnDestroy():
beforeEach(() => { fixture = TestBed.createComponent(Component); fixture.componentInstance.ngOnDestroy = () => null, }
spyOn ngOnDestroy():
beforeEach(() => { fixture = TestBed.createComponent(Component); spyOn(fixture.componentInstance, 'ngOnDestroy').and.callFake(() => null); }
spyOn fixture.destroy():
beforeEach(() => { fixture = TestBed.createComponent(Component); spyOn(fixture, 'destroy').and.callFake(() => null);
spyOn a component function:
// component: public ngOnDestroy(): void { this.reload(); } public reload(): void { window.location.reload; } // test: beforeEach(() => { fixture = TestBed.createComponent(Component); spyOn(fixture.componentInstance, 'reload').and.callFake(() => null);
spyOn reload:
beforeEach(() => { fixture = TestBed.createComponent(Component); spyOn(window.location, 'reload').and.callFake(() => null);
mock reload:
beforeEach(() => { fixture = TestBed.createComponent(component); window.location.reload = () => null,
mock location (this one gives wild results...):
beforeEach(() => { fixture = TestBed.createComponent(Component); window.location = {reload: () => null};
Solution 1:[1]
window
is your dependency, therefore, it should be injected as any other dependency, for example, as a token:
export const WINDOW = new InjectionToken('WINDOW');
then, in the module of Component
, you need to provide it:
@NgModule({
// ...
providers: [
{
provide: WINDOW,
useValue: window,
},
],
// ...
})
then, inject it in your Component
, you need to inject it as dependency:
export class Component {
constructor(@Inject(WINDOW) private window: Window) {}
public ngOnDestroy(): void {
this.window.location.reload(); // add this.
}
}
Now, you can mock it in your tests:
beforeEach(() => {
return TestBed.configureTestingModule({
declarations: [Component],
providers: [
{
provide: WINDOW,
useValue: {
location: {
reload: () => undefined, // or a spy
},
},
},
],
}).compileComponents();
});
Profit!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | satanTime |