i have a homecomponent where the html is
//home.component.html
<router-outlet></router-outlet>
//home.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HomeService} from './shared/services/home.service';
@Component({
// moduleId: module.id,
selector: 'app-home',
templateUrl: 'home.component.html',
styleUrls: ['home.component.css'],
providers:[HomeService]
})
export class HomeComponent implements OnInit {
constructor(private service:HomeService , private route:Router) { }
ngOnInit() {
if(this.service.isAuthenticated()){
this.route.navigateByUrl('dashboard/main');
}
}
}
//home.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { async, inject } from '@angular/core/testing';
import { HomeComponent } from './home.component';
import { Router} from '@angular/router';
import { HomeService } from './shared/services/home.service';
class RouterStub {
navigateByUrl(url: string) { return url }
}
class MockHomeService {
isAuthenticated() {
return true
}
}
let comp: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
describe('Component: HomeComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [HomeComponent],
providers: [
{ provide: Router, useClass: RouterStub },
{ provide: HomeService, useClass: MockHomeService },
]
});
fixture = TestBed.createComponent(HomeComponent);
comp = fixture.componentInstance;
});
it('should tell ROUTER to navigate to dashboard/main if authencated',
inject([Router, HomeService], (router: Router, homeservice: HomeService) => {
const spy = spyOn(router, 'navigateByUrl');
comp.ngOnInit();
if (homeservice.isAuthenticated()) {
const navArgs = spy.calls.first().args[0];
expect(navArgs).toBe('dashboard/main');
}
}));
});
I am getting the following error
Error: Template parse errors:
'router-outlet' is not a known element:
1. If 'router-outlet' is an Angular component, then verify that it is pa
rt of this module.
2. If 'router-outlet' is a Web Component then add "CUSTOM_ELEMENTS_SCHEM
A" to the '@NgModule.schema' of this component to suppress this message. ("<div
class="">
[ERROR ->]<router-outlet></router-outlet>
</div>
"): HomeComponent@1:4
at TemplateParser.parse (http://localhost:9876/_karma_webpack_/0.bun
dle.js:21444:19)
at RuntimeCompiler._compileTemplate (http://localhost:9876/_karma_we
bpack_/0.bundle.js:6569:51)
at http://localhost:9876/_karma_webpack_/0.bundle.js:6492:83
at Set.forEach (native)
at compile (http://localhost:9876/_karma_webpack_/0.bundle.js:6492:4
7)
at RuntimeCompiler._compileComponents (http://localhost:9876/_karma_
webpack_/0.bundle.js:6494:13)
at RuntimeCompiler._compileModuleAndAllComponents (http://localhost:
9876/_karma_webpack_/0.bundle.js:6411:37)
at RuntimeCompiler.compileModuleAndAllComponentsSync (http://localho
st:9876/_karma_webpack_/0.bundle.js:6399:21)
at TestingCompilerImpl.compileModuleAndAllComponentsSync (http://loc
alhost:9876/_karma_webpack_/0.bundle.js:10203:35)
at TestBed._initIfNeeded (webpack:///D:/myapp/transfer(9)/transfer/~
/@angular/core/bundles/core-testing.umd.js:1059:0 <- src/test.ts:4943:40)
what is the mistake i am doing ?
Thanks in advance
If you don't want to test routing but want to test the functionality of the component, you can just add
<!-- app.component.spec.ts -->
import { RouterTestingModule } from '@angular/router/testing';
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent],
});
This allows your test to run without disabling CUSTOM_ELEMENTS_SCHEMA
The error is because the <router-outlet>
in part of the RouterModule
1, which is not imported into your test bed configuration.
If you don't care to test any actual real routing (I notice the mock router), then you can just make Angular ignore the <router-outlet>
element by adding the following into your test bed configuration.
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
TestBed.configureTestingModule({
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
});
And just a suggestion. You want to test the behavior on the component, and the behavior is that when the component is created and the user authenticated, then the router navigate method should be called. So we should test that the navigate method is called. How do we do that? With Spies. You can make a spy from the navigateByUrl
method, then you can check with jasmine if that method was called
import { getTestBed } from '@angular/core/testing';
class RouterStub {
navigateByUrl = jasmine.createSpy('navigateByUrl');
}
it('should navigate', () => {
fixture.detectChanges();
let router: Router = getTestBed().get(Router);
expect(router.navigateByUrl).toHaveBeenCalledWith('dashboard/main');
});
Now you are getting a missing Http
provider error.
Because you have providers:[HomeService]
on your @Component
, it overrides the one in the test module configuration (which is the mock). You should override the component providers the in this case
TestBed.configureTestingModule({});
TestBed.overrideComponent(HomeComponent, {
set: {
providers: [
{ provide: HomeService, useClass: MockHomeService }
]
}
})
1 - For testing it should actually be the RouterTestingModule
, as mentioned here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With