首页 > 解决方案 > TypeError:在角度 5 中进行单元测试时无法读取未定义问题的属性“路径”

问题描述

我正在尝试对我的 angular5 应用程序进行单元测试。每次输入“ng test”命令时,它都会显示一些错误并解决它。但现在它返回一个新错误。

Chrome 64.0.3282 (Linux 0.0.0) ChannelsComponent should create FAILED
    TypeError: Cannot read property 'path' of undefined
        at new ChannelsComponent src/app/rcyc-components/rcyc-channels/rcyc-channels.component.ts:71:53)

我在我的组件中使用 activateRoute 来检索当前 url

this.currentUrlPathAsArray= this.activatedRoute.snapshot.url;       
this.currentUrlKey= this.currentUrlPathAsArray[0].path;

在上面使用激活路由的路径属性的代码中,我正在存储当前的 url。在我的应用程序上进行单元测试时,它会返回未定义错误的“路径”。

规格

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ChannelsComponent } from './rcyc-channels.component';
import { RouterModule } from "@angular/router";
import { NgxCarouselModule } from "ngx-carousel";
import { RcycDecodeHtmlPipe } from '../../rcyc-pipes/rcyc-decode-html/rcyc-decode-html.pipe';
import { RcycLimitPipe } from "../../rcyc-pipes/rcyc-limit/rcyc-limit.pipe";
import { RcycDefaultImagePipe } from '../../rcyc-pipes/rcyc-default-image/rcyc-default-image.pipe';
import { HttpClientModule } from '@angular/common/http';
import { RouterTestingModule } from '@angular/router/testing';
import { RcycCommonService } from '../../rcyc-services/rcyc-common/rcyc-common.service';
import { RcycChannelsService } from "./rcyc-channels.service";
describe('ChannelsComponent', () => {
  let component: ChannelsComponent;
  let fixture: ComponentFixture<ChannelsComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports:[RouterModule,NgxCarouselModule,HttpClientModule,RouterTestingModule],
      declarations: [ ChannelsComponent,RcycDecodeHtmlPipe,RcycLimitPipe,RcycDefaultImagePipe ],
      schemas:[CUSTOM_ELEMENTS_SCHEMA],
      providers:[RcycCommonService,RcycChannelsService]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ChannelsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

组件.ts

import { Component, OnInit, ViewEncapsulation } from "@angular/core";
// import { NgxCarousel , NgxCarouselStore} from "ngx-carousel";
import { Router, NavigationEnd, ActivatedRoute } from "@angular/router";
import { RcycChannelsService } from "./rcyc-channels.service";
import { AppConfig } from "../../rcyc-config/config";
import { RcycCommonService } from '../../rcyc-services/rcyc-common/rcyc-common.service';
import { NguCarousel,NguCarouselStore } from '@ngu/carousel';

@Component({
  selector: "app-channels",
  templateUrl: "./rcyc-channels.component.html",
  styleUrls: ["./rcyc-channels.component.css"],
  encapsulation: ViewEncapsulation.None,
  providers: [RcycChannelsService]
})
export class ChannelsComponent implements OnInit {

  public carouselOne: NguCarousel;
  deckTabObject: any;

  API_BASE_URL: any =   AppConfig.API_BASE_URL;
    IMG_BASE_URL: any =   AppConfig.IMG_BASE_URL;
    ELASTIC_API_BASE_URL: any =   AppConfig.ELASTIC_API_BASE_URL;

  tabcontent: any;
  basepath: any;
  apiResponseA: any;
  apiResponseB: any;
  apiResponseC: any;
  apiResponseD: any;
  apiResponseE: any;

  apiResponseATemp: any=[];
  apiResponseBTemp: any=[];
  apiResponseCTemp: any=[];
  apiResponseDTemp: any=[];
  apiResponseETemp: any=[];

  apiResponseAStatus: any = false;
  apiResponseBStatus: any = false;
  apiResponseCStatus: any = false;
  apiResponseDStatus: any = false;
  apiResponseEStatus: any = false;

  apiUrlA: any;
  apiUrlB: any;
  apiUrlC: any;
  apiUrlD: any;
  apiUrlE: any;
  apiUrlMetatag: any;

  currentUrlPathAsArray: any;
  currentUrlKey: any;
  currentComponentName: any;
  currentSlide:number = 0;

  constructor(

    private router: Router,
    private rcycChannelsService: RcycChannelsService,
    private rcycCommonService: RcycCommonService, 
    private activatedRoute: ActivatedRoute,   
  ) {

        // this.currentComponentName =  this.activatedRoute.routeConfig.component.name;                     
        this.currentComponentName = "RcycChannelsComponent";                        
        // Current subHeader Status
        this.rcycCommonService.changeSubHeaderStatus(true);

        this.currentUrlPathAsArray= this.activatedRoute.snapshot.url;       
        this.currentUrlKey= this.currentUrlPathAsArray[0].path;

        // To scroll up page
        this.router.events.subscribe(evt => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      window.scrollTo(0, 0);
    });

        var switchKey= this.currentUrlKey;
        switch(switchKey) {

            case "cruise-ports":

                    // change changeCurrentComponent
                    this.rcycCommonService.changeCurrentComponent(this.currentComponentName);

                    // Call get Metatag function 
                    this.apiUrlMetatag= "/api/v1/meta/destinations?_format=json";
                    this.rcycCommonService.getMetaTags(this.apiUrlMetatag);

                    this.rcycDestinationsContent();
            break;

            case "experience":

                    // Call get Metatag function 
                    this.apiUrlMetatag= "/api/v1/meta/experience?_format=json";
                    this.rcycCommonService.getMetaTags(this.apiUrlMetatag);

                    this.rcycExperienceContent();
            break;

            case "presailing":

                    // Call get Metatag function 
                    this.apiUrlMetatag= "/api/v1/meta/presailing?_format=json";
                    this.rcycCommonService.getMetaTags(this.apiUrlMetatag);

                    this.rcycPresailingContent();           
            break;

            default:

            break;

        }
    }

  ngOnInit() {

        // split url and redirection
    /*if(this.currentUrlKey == "cruise-ports") {

            this.rcycDestinationsContent();
        } else {

            this.rcycExperienceContent();
        }*/
        //Carousel settings
    this.carouselOne = {
      grid: { xs: 1, sm: 1, md: 1, lg: 1, all: 0 },
      slide: 1,
      speed: 500,
      interval: 300000,
      point: {
        visible: false
      },
      load: 3,
      touch: true,
      loop: true,
      custom: "banner"
    };

    //Tab options
    this.deckTabObject = [
      {
        name: "Onboard",
        class: "tab-link tab-link_suites is-active",
        contentClass: "tab-pane is-visible",
        active: true
      },
      {
        name: "Ashore",
        class: "tab-link",
        contentClass: "tab-pane",
        active: false
      }
    ];

  }

/* =============================================================================================================================================
        Function to display Full Api Urls of Destination 
 =============================================================================================================================================== */
  rcycDestinationsContent() {

    this.apiUrlA = "/api/v1/destinations/header/a?_format=json";
    this.apiUrlB = "/api/v1/destinations/content/b?_format=json";
    this.apiUrlC = "/api/v1/destinations/content/c?_format=json";
    this.apiUrlD = "/api/v1/regions?_format=json";    

    this.rcycChannelContent();

  }

/* =============================================================================================================================================
        Function to display Full Api Urls of Experience 
 =============================================================================================================================================== */
  rcycExperienceContent() {

        this.apiUrlA = "/api/v1/experience/header/a?_format=json";
        this.apiUrlB = "/api/v1/experience/content/b?_format=json";
    this.apiUrlC = "/api/v1/experience/content/c?_format=json";    
    this.apiUrlD = "/api/v1/experience/content/d?_format=json";

    this.rcycChannelContent();

  }

/* =============================================================================================================================================
        Function to display Full Api Urls of Presailing 
 =============================================================================================================================================== */
  rcycPresailingContent() {

        this.apiUrlA = "/api/v1/presailing/header/a?_format=json";
        this.apiUrlB = "/api/v1/presailing/content/b?_format=json";
    this.apiUrlC = "/api/v1/presailing/content/c?_format=json";    
    this.apiUrlD = "/api/v1/presailing/content/d?_format=json";

    this.rcycChannelContent();

  }

/* =============================================================================================================================================
        Function to display Full Apis Channels 
 =============================================================================================================================================== */
  rcycChannelContent() {

        /****************** Section A********************/

    this.rcycChannelsService.channels(this.apiUrlA).subscribe(
      response => {

                this.apiResponseATemp = response;
                if(this.apiResponseATemp.length) {

                    // var res= Object.values(response);
                    var res= Object.keys(response).map(function(key) {
                                                return response[key];
                                        });
                    if(res.length) {

                        this.apiResponseAStatus = true;
                        this.apiResponseA = response[0];

                        // Changing subheader A value
                        this.rcycCommonService.changeSubHeaderDataArray_A(this.apiResponseA);

                    } else {

                        // Changing subheader A value
                        this.rcycCommonService.changeSubHeaderDataArray_A([]);                      
                    }   
                } else {

                    // Changing subheader A value
                    this.rcycCommonService.changeSubHeaderDataArray_A([]);                      
                }   

            },
            err => {
                console.log(err);
            }
        );


    /******************Header  Section B********************/

        this.rcycChannelsService.channels(this.apiUrlB).subscribe(
      response => {

                this.apiResponseBTemp = response;
                if(this.apiResponseBTemp.length) {

                    // var res= Object.values(response);    
                    var res= Object.keys(response).map(function(key) {
                                                return response[key];
                                        });
                    if(res.length) {

                        var resArray=[];
                        for(let index in res) {

                            var factor= res[index];
                            if(factor.field_image) {

                                factor.field_image= this.IMG_BASE_URL+factor.field_image;

                                let imgTitle= this.rcycCommonService.imageNameAltSplit(factor.field_image);

                                factor.altTextBannerImg= factor.title+ " "+ imgTitle;
                                factor.titleTextBannerImg= factor.title+ " "+ imgTitle;
                            }else {

                                factor.altTextBannerImg= factor.title;
                                factor.titleTextBannerImg= factor.title;
                            }
                            resArray.push(factor);
                            if( parseInt(index)+1 == res.length ) {

                                this.apiResponseBStatus = true;
                                this.apiResponseB = resArray;

                            }
                        }                       
                    }
                }
      },
      err => {
        console.log(err);
      }
    );

    /****************** Section C********************/

    this.rcycChannelsService.channels(this.apiUrlC).subscribe(
      response => {

                this.apiResponseCTemp = response;
                if(this.apiResponseCTemp.length) {

                    // var res= Object.values(response);
                    var res= Object.keys(response).map(function(key) {
                                                return response[key];
                                        });
                    if(res.length) {

                        this.apiResponseCStatus = true;
                        this.apiResponseC = response[0];
                    }
                }

      },
      err => {
        console.log(err);
      }
    );

    /****************** Section D********************/

    this.rcycChannelsService.channels(this.apiUrlD).subscribe(
      response => {

                this.apiResponseDTemp = response;
                if(this.apiResponseDTemp.length) {

                    // var res= Object.values(response);
                    var res= Object.keys(response).map(function(key) {
                                            return response[key];
                                    });
                    if(res.length) {

                        var resArray= [];
                        for(let index in res) {

                            var factor= res[index];

                            if(factor.field_image) {

                                factor.field_image= this.IMG_BASE_URL+factor.field_image;

                                let imgTitle= this.rcycCommonService.imageNameAltSplit(factor.field_image);

                                factor.altTextOnBoardImg= factor.title+ " "+ imgTitle;
                                factor.titleTextOnBoardImg= factor.title+ " "+ imgTitle;
                            }else {

                                factor.altTextOnBoardImg= factor.title;
                                factor.titleTextOnBoardImg= factor.title;
                            }

                            if(this.currentUrlKey == 'cruise-ports') {

                                let field_group_url_keyNew= factor.field_group_url_key.toLowerCase();
                                factor.channelUrl="/luxury-"+field_group_url_keyNew+"-cruises";
                            } else if(this.currentUrlKey == 'experience') {

                                let field_url_keyNew= factor.field_url_key.toLowerCase();
                                factor.channelUrl="/experience/"+field_url_keyNew;
                            }


                            resArray.push(factor);                              
                            if( parseInt(index)+1 == res.length ) {

                                this.apiResponseDStatus = true;                         
                                this.apiResponseD = resArray;                                                           
                            }
                        }       

                    }
                } 

      },
      err => {
        console.log(err);
      }
    );



  }

  // Function on Learn more click
  learnMoreClick(event, item) {
        /****************** Section E********************/


    }


    nextCarouselload(ev) {
    // console.log(ev);
  }


   onmoveFn(data: NguCarouselStore) {
    this.currentSlide = data.currentSlide;
  }

  clickFn(data: NguCarouselStore){
this.currentSlide = data.currentSlide-1;
  }
}

我该如何解决这个问题?

标签: angular5karma-jasmine

解决方案


推荐阅读