angular - TypeError: Nu se poate citi proprietatea 'get' a valoarei indefinită (Rezolvarea importurilor conflictuale care nu funcționau)


Primesc o eroare când încerc să rulez fișierul de specificații TS pentru Karma. Toate modulele și importurile par să funcționeze bine, fără conflicte. Am încercat să adaug component.ngOninit() în beforeEach() și it(), dar nu am avut succes. Uitându-mă la probleme similare, acestea erau legate de un import conflictual HttpClientTestingModule sau de alte conflicte între providers/declarations. Nu am reușit să identific de ce TypeError: Cannot read property 'get' of undefined nu permite trecerea acestui fișier de specificații.

Fișier de specificații

import {async, ComponentFixture, TestBed} from '@angular/core/testing';

import {AcaPersonComponent} from './aca-person.component';
import {
  MatCardModule, MatDividerModule,
  MatFormFieldModule,
  MatIconModule,
  MatInputModule,
  MatOptionModule,
  MatRadioModule,
  MatSelectModule
} from '@angular/material';
import {ReactiveFormsModule} from '@angular/forms';
import {MFGDatePickerModule} from 'mfg-datepicker';
import {TextMaskModule} from 'angular2-text-mask';
import {AppRoutingModule} from '../../../../../app-routing.module';
import {HttpClientTestingModule} from '@angular/common/http/testing';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {LandingPageComponent} from '../../../../../landing-page/landing-page.component';

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        AcaPersonComponent,
        LandingPageComponent],
      imports: [MatFormFieldModule,
        ReactiveFormsModule,
        MatIconModule,
        MatInputModule,
        MFGDatePickerModule,
        MatOptionModule,
        MatSelectModule,
        MatRadioModule,
        MatCardModule,
        TextMaskModule,
        AppRoutingModule,
        BrowserAnimationsModule,
        HttpClientTestingModule,
        MatDividerModule
      ]
    })
      .compileComponents();
  }));

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

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

Eroare

TypeError: Cannot read property 'get' of undefined
    error properties: Object({ ngDebugContext: DebugContext_({ view: Object({ def: Object({ factory: Function, nodeFlags: 33669121, rootNodeFlags: 33554433, nodeMatchedQueries: 0, flags: 0, nodes: [ Object({ nodeIndex: 0, parent: null, renderParent: null, bindingIndex: 0, outputIndex: 0, checkIndex: 0, flags: 33554433, childFlags: 114688, directChildFlags: 114688, childMatchedQueries: 0, matchedQueries: Object({  }), matchedQueryIds: 0, references: Object({  }), ngContentIndex: null, childCount: 1, bindings: [  ], bindingFlags: 0, outputs: [  ], element: Object({ ns: '', name: 'app-aca-person', attrs: [  ], template: null, componentProvider: Object({ nodeIndex: 1, parent: <circular reference: Object>, renderParent: <circular reference: Object>, bindingIndex: 0, outputIndex: 0, checkIndex: 1, flags: 114688, childFlags: 0, directChildFlags: 0, childMatchedQueries: 0, matchedQueries: Object, matchedQueryIds: 0, references: Object, ngContentIndex: -1, childCount: 0, bindings: Array, bindingFlags: 0, outputs:  ...
        at <Jasmine>
        at AcaPersonComponent.get type [as type] (http://localhost:9876/_karma_webpack_/src/app/aca/aca-stepper/aca-steps/aca-step-2/aca-person/aca-person.component.ts:70:28)
        at AcaPersonComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/aca/aca-stepper/aca-steps/aca-step-2/aca-person/aca-person.component.ts:24:14)
        at checkAndUpdateDirectiveInline (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:31909:1)
        at checkAndUpdateNodeInline (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:44366:1)
        at checkAndUpdateNode (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:44305:1)
        at debugCheckAndUpdateNode (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:45327:36)
        at debugCheckDirectivesFn (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:45270:1)
        at Object.eval [as updateDirectives] (ng:///DynamicTestModule/AcaPersonComponent_Host.ngfactory.js:7:5)
        at Object.debugUpdateDirectives [as updateDirectives] (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:45258:1)
        at checkAndUpdateView (http://localhost:9876/_karma_webpack_/node_modules/@angular/core/fesm2015/core.js:44270:1)
    TypeError: Cannot read property 'get' of undefined
        at <Jasmine>
        at AcaPersonComponent.get type [as type] (http://localhost:9876/_karma_webpack_/src/app/aca/aca-stepper/aca-steps/aca-step-2/aca-person/aca-person.component.ts:70:28)
        at AcaPersonComponent.ngOnInit (http://localhost:9876/_karma_webpack_/src/app/aca/aca-stepper/aca-steps/aca-step-2/aca-person/aca-person.component.ts:24:14)
        at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/src/app/aca/aca-stepper/aca-steps/aca-step-2/aca-person/aca-person.component.spec.ts:58:15)
        at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:365:1)
        at ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:305:1)
        at ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:364:1)
        at Zone.run (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:124:1)
        at runInTestZone (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:554:1)
        at UserContext.<anonymous> (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:569:1)
        at <Jasmine>

Clasa TS

import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {FormGroup, Validators} from '@angular/forms';
import {merge} from 'rxjs';

@Component({
  selector: 'app-aca-person',
  templateUrl: './aca-person.component.html',
  styleUrls: ['./aca-person.component.css']
})
export class AcaPersonComponent implements OnInit {

  @Input() personType: string;
  @Input() peopleForm: FormGroup;
  @Input() nextWasClicked: boolean;
  @Input() index: number;
  @Output() removePerson = new EventEmitter<boolean>();
  cardTitle: string;
  personAge: number;

  constructor() {
  }

  ngOnInit() {
    if (this.type.value == 'primary') {
      this.cardTitle = 'Your Information';
    } else if (this.type.value == 'spouse') {
      this.cardTitle = 'Spouse';
    } else if (this.type.value == 'dependent') {
      this.cardTitle = 'Dependent';
    }
    this.dobAndIsPregnantVC();
  }

  dobAndIsPregnantVC() {
    merge(
      this.dob.valueChanges,
      this.gender.valueChanges
    )
      .subscribe(() => {
        this.calculateAge(this.dob.value);
        if (this.gender.value == 'F') {
          this.is_pregnant.setValidators(Validators.required);
          if (this.personAge < 14) {
            this.is_pregnant.setValue(null);
            this.is_pregnant.clearValidators();
          }
        } else {
          this.is_pregnant.setValue(null);
          this.is_pregnant.clearValidators();
        }
        this.is_pregnant.updateValueAndValidity();
      });
  }

  // Calculate the age of the client from their birth date to display in the census details
  private calculateAge(date: string) {
    if (date) {
      const timeDiff = Math.abs(Date.now() - new Date(date).getTime());
      this.personAge = Math.floor(timeDiff / (1000 * 3600 * 24) / 365.25);
    }
  }

  onRemovePerson() {
    this.removePerson.emit(true);
  }

  // GETTERS

  get type() {
    return this.peopleForm.get('type');
  }

  get first_name() {
    return this.peopleForm.get('first_name');
  }

  get last_name() {
    return this.peopleForm.get('last_name');
  }

  get gender() {
    return this.peopleForm.get('gender');
  }

  get dob() {
    return this.peopleForm.get('dob');
  }

  get uses_tobacco() {
    return this.peopleForm.get('uses_tobacco');
  }

  get affordable_care() {
    return this.peopleForm.get('affordable_care');
  }

  get is_pregnant() {
    return this.peopleForm.get('is_pregnant');
  }


}

Răspuns #1

Se întâmplă deoarece nu există @Input definite în cazul tău de test, așa că trebuie să le creezi astfel:

  beforeEach(() => {
    fixture = TestBed.createComponent(AcaPersonComponent);
    component = fixture.componentInstance;
    component.peopleForm = fb.group({
       type:  ['Other Name', Validators.required],
       first_name: ['f_name', Validators.required],
       //.. and so on for all params
    });
    component.personType = 'Some Type';
    component.nextWasClicked = true;
    component.index = 1; // or whatever is required
    fixture.detectChanges();
  });


Acest lucru te va ajuta să definești this.peopleForm și astfel liniile ca this.peopleForm.get('type'); nu vor da astfel de erori

Nu este nevoie să adaugi component.ngOnInit()