In the example below, after running ng test --include my-component.component.spec.ts, I'm getting this error:
An error was thrown in afterAll Uncaught ReferenceError: Cannot access 'MyComponentComponent' before initialization
I think this is due to a circular dependency, because my component access a route file where the component itself is referenced.
my-component.component.ts
import {Component, OnInit} from '@angular/core';
import {myRoutes} from './my-routes';
@Component({
selector: 'mi-component',
template: ``,
})
export class MyComponentComponent implements OnInit {
ngOnInit(): void {
}
routesModification() {
const routes = myRoutes;
routes[0].path = '/new-route';
}
}
my-component.component.spec.ts
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MyComponentComponent} from './my-component.component';
describe('MyComponentComponent class', () => {
let component: MyComponentComponent;
let fixture: ComponentFixture<MyComponentComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MyComponentComponent],
imports: [],
providers: [],
}).compileComponents();
fixture = TestBed.createComponent(MyComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('El componente deberia estar creado correctamente', () => {
expect(component).toBeTruthy();
});
});
my-routes.ts
import {Routes} from '@angular/router';
import {MyComponentComponent} from './my-component.component';
export const myRoutes: Routes = [
{
path: '',
component: MyComponentComponent,
},
];
I need to fix this so that the test passes without touching the component or the route files, which I am not allowed. This is a problem that occurs only when I launch the test individually, when I launch the application or when I launch ng test globally, no such message appears.
We create a dummy component assign it to the default route, to bypass this error message, you can revert it to the original component on the beforeEach
or afterAll
, but the bottom solution is the proper one I feel.
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MyComponentComponent } from './my-component.component';
import { myRoutes } from './my-routes';
import { Component } from '@angular/core';
@Component({
selector: 'dummy',
})
export class DummyComponent {}
describe('MyComponentComponent class', () => {
let component: MyComponentComponent;
let fixture: ComponentFixture<MyComponentComponent>;
beforeEach(async () => {
myRoutes[0].component = DummyComponent;
await TestBed.configureTestingModule({
declarations: [MyComponentComponent],
imports: [],
providers: [],
}).compileComponents();
fixture = TestBed.createComponent(MyComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('El componente deberia estar creado correctamente', () => {
expect(component).toBeTruthy();
});
});
I think you have accessed routes which already contains the same component (import {myRoutes} from './my-routes';
) you are accessing it before it is defined (export class MyComponentComponent implements OnInit {
).
Instead try to access the routes through the router config
property, then update the routes, finally use resetConfig
to apply the routes again.
import { Component, inject, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'mi-component',
template: ``,
})
export class MyComponentComponent implements OnInit {
router = inject(Router);
ngOnInit(): void {}
routesModification() {
const routes = this.router.config; // <- changed here!
routes[0].path = '/new-route'; // <- changed here!
this.router.resetConfig(routes); // <- changed here!
}
}