角单元测试:TypeError:无法读取未定义的属性“ root”

菲拉斯·库巴

我正在Angular应用程序下进行单元测试。

我的Angular版本是4.0.0。

我的组件如下所示:

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>

如您所见,我没有使用routeLink

在我的测试文件配置中,我这样做:

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();
    });
});

尽管我已经导入NO_ERRORS_SCHEMA并且使用了mockRouter,但似乎仍然存在以下错误:

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

从日志的最后一行指向53:27行,这恰好是:

fixture = TestBed.createComponent(QueueAgainComponent);

因此,似乎无法创建Fixture

有任何想法吗?

eter

我有同样的问题,只是想通了。删除行:

{provide: Router, useValue: mockRouter}

它会工作。

问题是,当您导入时RouterTestingModule,应删除所有路由器模拟的提供程序,另存为ActiveRoute等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Angular 2单元测试-无法读取未定义的属性“ root”

Vue无法读取未定义的属性“ $ root”

使用业力进行角单元测试:会话存储“无法读取未定义的属性”

Jasmine 单元测试 - TypeError:无法读取未定义的属性(读取“管道”)

玩笑和酶单元测试:TypeError:无法读取未定义的属性“ push”

反应开玩笑的单元测试用例TypeError:无法读取未定义的属性'then'

渲染错误:“TypeError:无法读取未定义的属性‘_t’”在单元测试中使用 Jest

Angular 8:ActivatedRoute 上的 Jasmine 单元测试,TypeError:无法读取未定义的属性“父”

Angular 4单元测试错误“ TypeError:无法读取未定义的属性'subscribe'”

单元测试 Angular 4 出现错误“TypeError:无法读取未定义的属性“订阅”

Angular 单元测试 - TypeError:无法读取未定义的属性“名称”

无法读取本机基本ActionSheet上未定义的属性“ _root”

使用Chai进行单元测试时,“ TypeError:无法读取未定义的属性'address'”是什么意思?

[karma-server]:TypeError:无法读取未定义的属性“范围”-CI环境中的角度单元测试

TypeError:无法读取未定义的属性'getParam'。使用玩笑和酶反应本机单元测试?

TypeError:在angular2中执行单元测试时,无法读取未定义故障的属性“快照”

运行npm测试(Angular 2单元测试)后无法读取未定义的属性“ subscribe”

茉莉花单元测试-无法读取未定义的属性管道

在Chai中进行单元测试时,无法读取未定义的属性“ apply”

在 Jasmine 中对 MatDialog 进行单元测试时,无法读取未定义的属性“afterClosed”

无法读取单元测试错误中未定义的属性 setNumber

Angular 2单元测试“无法读取未定义的属性'unsubscribe'”

单元测试中的角度“无法读取未定义的属性'subscribe'”

无法读取离子2单元测试中未定义的属性'_getPortal'

无法读取未定义的单元测试酶的属性“ contextTypes”

Angular 单元测试为 Http Post 返回“无法读取未定义的属性”

类型错误:在单元测试 Angular 6 时无法读取未定义的属性“查询”

angular2单元测试:无法读取componentInstance.method()的属性未定义

无法读取未定义的'ngOnInit''getData'的属性-角度单元测试-茉莉花