Home > other >  Karma-Jasmine: TypeError: Cannot read properties of undefined (reading 'get')
Karma-Jasmine: TypeError: Cannot read properties of undefined (reading 'get')

Time:11-03

I am trying to write a unit test for my angular component and I am stuck at this error. I have researched a lot about this on stack overflow and some online docs. Here is the link of resources which I have tried so far with no luck.

https://dev.to/amerigom/how-to-activatedroute-in-angular-and-how-to-mock-it-in-unit-tests-2ne6

How to unit test a component that depends on parameters from ActivatedRoute?

How do you mock ActivatedRoute

Below is my code

.ts file

import { ResourceOverviewService } from '../../../../services/detail/resource-overview/resource-overview.service'
import {
  Component,
  OnInit,
} from '@angular/core';
import { UtilsService } from '../../../../services/common/utils.service';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
  selector: 'app-resource-overview',
  templateUrl: './resource-overview.component.html',
  styleUrls: ['./resource-overview.component.scss']
})
export class ResourceOverviewComponent implements OnInit {
  uuid = '--';
  resourceName = '--';
  status = '--';
  provider = '--';
  providerAccount = '--';
  resourceCategory = '--';
  resourceType = '--';
  region = '--';
  overviewTags = '--';
  correlationID = '--';
  showMore = true;
  crn = '--'
  lastupdated : any;
  providerAccountName = '--'
  resourceId = '--'
  creationDate = '--'
  description = '--'
  tags = '--'
  dateTimeFormat = 'MMM d, y h:mm a';
  lastUpdateTime: any;
  dateTimeZone: any;
  keyValue : { key: any, value: any }[] = [];
  id = '--';
  providerLastUpdated = '--';
  providerStatus = '--';
  breadcrumbs = [];
  launchpadURL = `/launchpad`;
  
  constructor(
    private readonly resourceOverviewService: ResourceOverviewService,
    private readonly utilsService: UtilsService,
    private readonly router: Router,
    readonly route: ActivatedRoute,
  ) {}

  ngOnInit() {
    this.id = this.route.snapshot.queryParamMap.get('id');
    this.getDetails();
  }

  viewInventory(){
    this.router.navigate(['..'], {
      relativeTo: this.route
    });
  }

  getDetails() {
    if (this.id) {
      this.getResourceOverview();
    }
  }

  getResourceOverview(): void {
    const resourceID = `search_keys=${"resource_id"}&search=${this.id}`
    this.resourceId = this.id
    this.resourceOverviewService
      .getResourceOverview(resourceID)
      .subscribe(
        (response) => {
          const result = response as any;
          if (result && something) {
            this.uuid = something  || '--';
            this.creationDate = something || '--' ;
            this.correlationID = something || '--' ;
            this.providerStatus = something || '--' ;
          }
        },
        (error) => {
          console.log('Resource overview details failed with error', error);
        }
      );
  }
}

.ts.spec

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { HttpWrapperService } from '../../../../services/common/http-wrapper.service';
import { ResourceOverviewComponent } from './resource-overview.component';
import { NGXLogger } from 'ngx-logger';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { CarbonComponentsModule } from '@cloudMatrix-CAM/cb-carbon-components-lib';
import { CarbonModule } from '../../../../../carbon.module';
import { ApiContractService, CbTranslationUiLibModule, TranslationService,AuthenticationContractService } from '@cloudMatrix-CAM/cb-common-ui';
import { MockNGXLogger } from '../../../../components/discovery-inventory/list-view/list-view.component.spec';
import { convertToParamMap, Router } from '@angular/router';
import { ApiService } from '../../../../services/common/api.service';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CbCommonDiscoveryManagementMicroUiService } from '../../../../services/cb-common-discovery-management-micro-ui.service';
import { ActivatedRoute } from "@angular/router";
import { throwError, of, Observable  } from 'rxjs';
import { RouterModule } from '@angular/router'
class mockHttpWrapperService {
  readonly isApiReady = false;
}

describe('ResourceOverviewComponent', () => {
  let component: ResourceOverviewComponent;
  let fixture: ComponentFixture<ResourceOverviewComponent>;
  let activatedRouteSpy;

  beforeEach(async(() => {
    activatedRouteSpy = {
      snapshot: {
        paramMap: convertToParamMap({
          id: 'dads123',
          code: 'IBM',
        })
      }
    };
    TestBed.configureTestingModule({
      declarations: [ResourceOverviewComponent],
      imports: [
        CarbonComponentsModule, CarbonModule, CbTranslationUiLibModule.forRoot(),
        RouterModule.forRoot([])
      ],
      providers: [
        { provide: NGXLogger, useClass: MockNGXLogger },
        { provide: HttpWrapperService, useClass: mockHttpWrapperService },
        { provide: Router, useClass: class { navigate = jasmine.createSpy("navigate"); }},
        ApiContractService,
        TranslationService,
        ApiService,
        ApiContractService,
        TranslationService,
        CbCommonDiscoveryManagementMicroUiService,
        {
         provide: ActivatedRoute,
         useValue: activatedRouteSpy
        }
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
    })
    .compileComponents()
    .then(() => {
      fixture = TestBed.createComponent(ResourceOverviewComponent);
      component = fixture.debugElement.componentInstance;
      fixture.detectChanges();
      component.ngOnInit();
    })
  }));

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

And below is the error message Chrome 93.0.4577 (Linux 0.0.0) ResourceOverviewComponent should create 1 FAILED TypeError: Cannot read properties of undefined (reading 'get')

Can anyone help me out with this error?

CodePudding user response:

In your test setup you provide the following activated route:

activatedRouteSpy = {
  snapshot: {
    paramMap: convertToParamMap({
      id: 'dads123',
      code: 'IBM',
    })
  }
};

And in your ngOnInit you access it like this:

this.id = this.route.snapshot.queryParamMap.get('id');

Your spy does not have a queryParamMap property, but only a paramMap. Rename it in your spy or supply both, the paramMap and a queryParamMap if you need both further down the line.

  • Related