mercredi 22 mai 2019

Angular test issue with mocks - "Cannot set property '2' of undefined"

I'm not sure why i got this error here. I post important parts of code what i wan't to test:

spec.ts:

import { SavedLand } from './saved-land';

const selectedSavedLandMock: SavedLand[] = [
  {
    id: 2,
    parcelId: '0858897347895789237897895',
    name: 'CJ mansion',
    sizeAcres: 10,
    city: 'Los Santos',
    county: 'Red County',
    state: 'San Andreas',
    estCost: 1000000,
    company: 'Groove Street',
    isEdited: false
  }
];

describe('SavedLandComponent', () => {
  let SUT: SavedLandComponent;
  let fixture: ComponentFixture<SavedLandComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        SavedLandComponent,
        WindowComponent,
        CanvasComponent
      ],
      imports: [
        PrimeNgModule,
        BrowserAnimationsModule,
        NoopAnimationsModule,
        TranslateModule,
        HttpClientModule
      ],
      providers: [
        WindowService,
        {
          provide: Store,
            useValue: jasmine.createSpyObj('Store', ['select', 'dispatch'])
        },
        {
          provide: TranslateService,
          useClass: TranslateServiceStub
        }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SavedLandComponent);
    SUT = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('should toggle edit', () => {
    const selectedSavedLand: SavedLand[] = selectedSavedLandMock;
    SUT.onRowEditNameInit(selectedSavedLand[0]);
    expect(selectedSavedLand[0].isEdited).toBeTruthy();
  });

  it('should save edit' , () => {
    let selectedSavedLand: SavedLand[] = selectedSavedLandMock;
    //selectedSavedLand[0].name = 'Big Smoke Crib';
    SUT.onRowEditNameInit(selectedSavedLand[0]);
    SUT.onRowEditNameSave(selectedSavedLand[0]);
    expect(selectedSavedLand[0].isEdited).toBeFalsy();
    //expect(selectedSavedLand[0].name).toBe('Big Smoke Crib');
  });
});

ts:

import { Component, OnInit } from '@angular/core';
import { SavedLandState, SavedLand } from './saved-land';
import { Store, select } from '@ngrx/store';
import { MenuItem, DialogService } from 'primeng/api';
import { TranslationHelpersService } from '../../../layout-shell/translation-helpers/translation-helpers.service';
import { Observable } from 'rxjs';
import { getLandsList, savedLandReducer } from './saved-land.reducer';
import { LandsBackendService } from '../services/lands-backend.service';
import * as saveParcelActions from './saved-land.actions';
import { RemoveParcel } from './../saved-land/saved-land.actions';

@Component({
  selector: 'app-saved-land',
  templateUrl: './saved-land.component.html',
  styleUrls: ['./saved-land.component.scss']
})
export class SavedLandComponent implements OnInit {


  public clonedParcels: { [s: string]: SavedLand; } = {};

  private contextMenuItems: MenuItem[];
  constructor(private store: Store<SavedLandState>,
              private serviceLand: LandsBackendService,
              public translateHelperService: TranslationHelpersService) { }

  public savedLands: Observable<SavedLand[]>;
  public selectedSavedLand: SavedLand;

  public cols: any[];

  public onRowEditNameInit(savedLand: SavedLand) { //Need tests\
    if(savedLand.isEdited === false){
      savedLand.isEdited = true;
      this.clonedParcels[savedLand.id] = {...savedLand};
    }
  }

  public onRowEditNameSave(savedLand: SavedLand) { //Need tests
    savedLand.isEdited = false;
    this.savedLands[savedLand.id] = savedLand;
    delete this.clonedParcels[savedLand.id];
  }

  public onRowEditNameUndo(savedLand: SavedLand, index: number) { //Need tests
    savedLand.isEdited = false;
    this.savedLands[index] = this.clonedParcels[index];
    savedLand.name = this.clonedParcels[savedLand.id].name;
    delete this.clonedParcels[savedLand.id];
  }

  public removeParcelFromStore(index: number): void {
    this.store.dispatch(new RemoveParcel(index));
  }

  public ngOnInit() {
    this.store.dispatch(new saveParcelActions.GetAllParcels());
    this.savedLands = this.store.select(getLandsList);

    this.contextMenuItems = [
      {label: 'OpenDetails'},
      {
        label: 'RenameParcel',
        command: () => this.onRowEditNameInit(this.selectedSavedLand)
      },
      {
        label: 'DeleteParcel',
        command: () => this.removeParcelFromStore(this.selectedSavedLand.id)
      }
    ];

    this.cols = [
      { field: 'name', label: 'Name' },
      { field: 'sizeAcres', label: 'Size' },
      { field: 'city', label: 'City' },
      { field: 'state', label: 'State' },
      { field: 'estCost', label: 'EstCost' },
      { field: 'company', label: 'Company' }
    ];

    this.translateHelperService.translateItems(this.contextMenuItems);
    this.translateHelperService.translateItems(this.cols);
  }
}

error:

TypeError: Cannot set property '2' of undefined at SavedLandComponent../src/app/workspace/land/saved-land/saved-land.component.ts.SavedLandComponent.onRowEditNameSave (src/app/workspace/land/saved-land/saved-land.component.ts:41:34) at UserContext. (src/app/workspace/land/saved-land/saved-land.component.spec.ts:84:9)

Aucun commentaire:

Enregistrer un commentaire