I'm working on unit testing under my Angular app.
My version of Angular is 4.0.0.
My component look like this:
component.ts
:
import { GdfaClientService } from '../../../service/gdfa-client.service'; import { SharedclientService } from '../../../service/sharedclient.service'; import { Client } from '../../model/client'; import { RouteNavigator } from '../../util/route-navigator'; import { Component, OnInit } from '@angular/core'; import {MonitoringService} from '../../../service/monitoring.service'; @Component({ selector: 'app-queue-again', templateUrl: './queue-again.component.html', styleUrls: ['./queue-again.component.css'], }) export class QueueAgainComponent implements OnInit { //-- variables --// showError = false; queueChoices = []; selectedQueue; selectedReason; requestInProgress = false; client: Client; errorMessage: string; queues: any; bankNotAllowed: boolean = false; constructor(private sharedclientService: SharedclientService, private gdfaClientService: GdfaClientService , private router: RouteNavigator, private monitoringService: MonitoringService) { } ngOnInit() { this.client = this.sharedclientService.getShared360Client(); this.getQueues(); this.bankNotAllowed = this.sharedclientService.bankNotAllowed; } goToPrevious() { this.router.goToHomeAccordingToProfile(); } queueAgain() { let currentNd = ""; let currentUniverse = ""; let currentCuid = ""; if (!this.selectedReason) { return; } this.requestInProgress = true; let reg = { registrationId: this.client.registration.gdfaId, gdfaQueueId: this.selectedQueue.id, gdfaReasonId: this.selectedReason.id, firstProfile: (this.client.firstProfile ? true : false) }; this.gdfaClientService.queueAgain(reg).then(any => { currentCuid = this.client.clientIdentity.customerId; if (this.client.fromAdvSearch == undefined || this.client.fromAdvSearch == false) { currentNd = this.client.nd; if (currentNd != undefined && currentNd != "") { if (currentNd == "0000000000") { currentNd = ""; currentUniverse = ""; } if (currentNd.substring(0, 2) == "06" || currentNd.substring(0, 2) == "07") { currentUniverse = "Mobile"; } else { currentUniverse = "Fixe"; } } } this.trackReinsertClient(currentCuid, currentNd, currentUniverse); this.requestInProgress = false; this.showError = false; this.sharedclientService.setShared360Client(new Client()); this.goToPrevious(); }) .catch(error => { this.requestInProgress = false; this.showError = true; switch (error.status) { case 403: this.errorMessage = "Erreur lors de la réinjection du client : utilisateur inconnu"; console.log(this.errorMessage); break; case 500: this.errorMessage = "Réinscription impossible"; console.log(this.errorMessage); break; default: this.errorMessage = "Erreur lors de la réinjection du client"; console.log(this.errorMessage); } }); }; trackReinsertClient(cuid, nd, universe) { let uri = "/api/gdfa/client/registration/reinsert"; let httpMethod = "PUT"; let name = "réinjection d'un client dans la file d'attente"; console.log('trackReinsertClient <' + cuid + '>'); this.monitoringService.trackingAction(name, uri, httpMethod, null, cuid, nd, universe); } selectQueue(queue) { this.selectedQueue = queue; this.selectedReason = false; }; isSelectedQueue(queue) { return this.selectedQueue.shortName == queue.shortName; } getQueues() { let queueList = this.client.registration.queueAgainChoices; // Search for residentiel queue and put it as selectedQueue let indexSAVSAUMobile = -1; let indexSAVSAUInternet = -1; for (let queue of queueList) { if (queue.shortName == 'RES') this.selectedQueue = queue; } this.queues = queueList; return queueList; } selectReason(reason) { this.selectedReason = reason; } isSelectedReason(reason) { if (this.selectedReason) { return this.selectedReason.id == reason.id; } return null } getReasons(queue) { let reasonList = this.selectedQueue.reasons; return reasonList; } }
component.html
:
<div> <div [hidden]="!requestInProgress" id="div-spinner"> <img src="/assets/images/indicateur-attente-grand.gif" class="spinner-loader" /> </div> <div class="row"> <!-- fermeture de la recherche avancée --> <div class="col-xs-1 pull-right closeCross"> <img id="ngClick_goToPreviousFromQueueAgain" src="/assets/images/asset_icon_close_popup_gray.png" class="pull-right mousePointer" (click)="goToPrevious()" /> </div> </div> <div class="row"> <div class="col-xs-10 col-xs-offset-1 error-message" *ngIf="showError">{{errorMessage}}</div> <div class="col-xs-10 col-xs-offset-1 col-sm-3 col-sm-offset-0 register-bloc"> <div class="titre_bloc">File d'attente</div> <div id="files-bloc"> <div id="ngClick_selectQueueAgain" class="file-cell " *ngFor="let queue of queues | orderBy : 'id'" [ngClass]="{ 'selected-shop-queue': isSelectedQueue(queue)}" (click)='selectQueue(queue)'> <div class="vertical-center horizontal-middle file_nom"> <div>{{queue.name}}</div> </div> </div> </div> </div> <div class="col-xs-10 col-xs-offset-1 col-sm-6 col-sm-offset-0 register-bloc"> <div class="titre_bloc">Motifs</div> <div id="motifs-bloc"> <div id="ngClick_queueAgain" class="motif-cell" [ngClass]="{'motif-cell-pro': selectedQueue?.reasons?.length == 4, 'motif-cell-selected':isSelectedReason(reason), 'hide-class': (bankNotAllowed && reason.id === 12)}" [hidden]="bankNotAllowed && reason.id === 12" *ngFor="let reason of selectedQueue?.reasons | orderBy : 'motifOrder'" (click)='selectReason(reason)'> <div *ngIf="!bankNotAllowed || reason.id !== 12" class="mIcon"> <img src="/bower_components/nomadis/images-no-cache/{{reason?.imageName}}" [ngClass]="{'motif-unique': client?.registration?.queue?.reasons?.length == 1}" /> <span>{{reason.name}}</span> </div> </div> </div> <div class="col-sm-offset-4 col-sm-4 btn-validate-reinsert"> <input id="validateReinsertBtn" type="submit" value="Valider" [ngClass]="{'queueAgain-disabled': !selectedReason}" class="btn btn-lg btn-primary btn-block" (click)='queueAgain()' /> </div> </div> </div> </div> <router-outlet></router-outlet>
As you can see I'm not using routeLink
.
Within my test file config I've done this:
component.spec.ts
:
import {async, ComponentFixture, TestBed, tick, fakeAsync} from '@angular/core/testing'; import {QueueAgainComponent} from './queue-again.component'; import {OrderByPipe} from 'app/home/pipe/order-by.pipe'; import {SharedclientService} from 'app/service/sharedclient.service'; import {GdfaClientService} from 'app/service/gdfa-client.service'; import {AuthHttp, AuthConfig, AUTH_PROVIDERS, provideAuth} from 'angular2-jwt'; import {HttpModule} from '@angular/http'; import {EnvVarsService} from 'app/service/env-vars.service'; import {RouteNavigator} from 'app/home/util/route-navigator'; import {Router} from '@angular/router'; import {Observable} from 'rxjs/Observable'; import * as QueueAgainMocks from 'TU/mocks/queue-again-mocks'; import {RouterTestingModule} from '@angular/router/testing'; import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('QueueAgainComponent', () => { let comp: QueueAgainComponent; let fixture: ComponentFixture<QueueAgainComponent>; let sharedclientService: SharedclientService; let gdfaClientService: GdfaClientService; let getShared360Client: jasmine.Spy; let queueAgain: jasmine.Spy; let client = QueueAgainMocks.CUSTOMER_MOCK; let selectedQueue = QueueAgainMocks.SELECTED_QUEUE_MOCK; let selectedReason = QueueAgainMocks.SELECTED_REASON; let mockRouter = { navigate: jasmine.createSpy('navigate') }; // TestBed preparation (async) beforeEach(async(() => { TestBed.configureTestingModule({ imports: [HttpModule , RouterTestingModule], declarations: [QueueAgainComponent, OrderByPipe], providers: [SharedclientService, GdfaClientService, AuthHttp, EnvVarsService, RouteNavigator, {provide: Router, useValue: mockRouter}, provideAuth({ headerName: 'Authorization', headerPrefix: 'bearer', tokenName: 'token', tokenGetter: (() => localStorage.getItem('id_token')), globalHeaders: [{'Content-Type': 'application/json'}], noJwtError: true }) ], schemas: [ NO_ERRORS_SCHEMA ] }).compileComponents(); })); // Fixture & Spies declarations beforeEach(() => { // Creation of the component fixture fixture = TestBed.createComponent(QueueAgainComponent); comp = fixture.componentInstance; fixture.detectChanges(); // this line will call components ngOnInit() method // Getting Services instances from fixture sharedclientService = fixture.debugElement.injector.get(SharedclientService); gdfaClientService = fixture.debugElement.injector.get(GdfaClientService); // Call of fake methods of `sharedclientService` from the AlertServiceSpy getShared360Client = spyOn(sharedclientService, 'getShared360Client').and.returnValue(client); // Call of fake methods of `gdfaClientService` from the AlertServiceSpy queueAgain = spyOn(gdfaClientService, 'queueAgain').and.callFake((reg) => { return Observable.of('ok'); }); comp.ngOnInit(); }); // Test case of component compilation it('should be defined', () => { expect(comp).toBeDefined(); }); });
Although I've imported NO_ERRORS_SCHEMA
and I've used a mockRouter
, it seems that something is still going wrong with routing with this error:
TypeError: Cannot read property 'root' of undefined at rootRoute (node_modules/@angular/router/bundles/router.umd.js:6110:30) at _callFactory (packages/core/src/view/ng_module.ts:185:1) at _createProviderInstance$1 (packages/core/src/view/ng_module.ts:124:1) at resolveNgModuleDep (node_modules/@angular/core/bundles/core.umd.js:9517:17) at _createClass (packages/core/src/view/ng_module.ts:158:1) at _createProviderInstance$1 (packages/core/src/view/ng_module.ts:121:1) at resolveNgModuleDep (node_modules/@angular/core/bundles/core.umd.js:9517:17) at NgModuleRef_.Object.<anonymous>.NgModuleRef_.get (node_modules/@angular/core/bundles/core.umd.js:10609:16) at resolveDep (node_modules/@angular/core/bundles/core.umd.js:11112:45) at createClass (node_modules/@angular/core/bundles/core.umd.js:10976:32) at createDirectiveInstance (node_modules/@angular/core/bundles/core.umd.js:10796:37) at createViewNodes (packages/core/src/view/view.ts:354:1) at createRootView (node_modules/@angular/core/bundles/core.umd.js:12139:5) at callWithDebugContext (packages/core/src/view/services.ts:815:1) at Object.debugCreateRootView [as createRootView] (node_modules/@angular/core/bundles/core.umd.js:12842:12) at ComponentFactory_.Object.<anonymous>.ComponentFactory_.create (node_modules/@angular/core/bundles/core.umd.js:9904:46) at initComponent (node_modules/@angular/core/bundles/core-testing.umd.js:924:49) at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:392:26) at ProxyZoneSpec.Object.<anonymous>.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:79:39) at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:391:32) at Object.onInvoke (node_modules/@angular/core/bundles/core.umd.js:3922:33) at ZoneDelegate.Object.<anonymous>.ZoneDelegate.invoke (node_modules/zone.js/dist/zone-node.js:391:32) at Zone.Object.<anonymous>.Zone.run (node_modules/zone.js/dist/zone-node.js:142:43) at NgZone.Object.<anonymous>.NgZone.run (node_modules/@angular/core/bundles/core.umd.js:3853:69) at TestBed.Object.<anonymous>.TestBed.createComponent (packages/core/testing/src/test_bed.ts:471:1) at Function.Object.<anonymous>.TestBed.createComponent (node_modules/@angular/core/bundles/core-testing.umd.js:691:29) at src/app/home/advisor/queue-again/queue-again.component.spec.ts:53:27
From the last line of the log that points on the 53:27 line which is exactly:
fixture = TestBed.createComponent(QueueAgainComponent);
So it seems that it's not able to create the fixture.
Any ideas?
I had the same problem, just figured it out. Remove the line:
{provide: Router, useValue: mockRouter}
and it will work.
The thing is when you import RouterTestingModule
you should remove all router mocked providers, save for ActiveRoute
, etc.
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