Как создать экземпляр / макет интерфейса при тестировании компонента angular? - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь протестировать компонент Angular, который имеет функцию bindProjectData. Эта функция использует две службы (ClientStoreService и ProjectService). Ответы от этих сервисов хранятся в переменных класса. Одной из переменных класса (allProjects) является Interface [].

Во время тестирования этой функции, независимо от того, что я делаю, эта переменная allProjects не определена. Я издевался над сервисом. Возвращает значение. Я попытался создать фиктивный интерфейс и попытался создать переменную component.allProjects в моем файле spe c. Ничего не работает.

Ниже приведен компонент и его файл spe c.

component.ts

  public allProjects: IProjectListItem[];
  rows = [];
  ColumnMode = ColumnMode;
  sortFn: any;
  isLoaded = false;
  // Added successMessage and errorMessage variables
  successMessage: string = null;
  errorMessage: string = null;

  constructor(
    private router: Router,
    private toastr: ToastrService,
    private projectService: ProjectService,
    private currencyPipe: CurrencyPipe,
    private datePipe: DatePipe,
    public userService: UserService,
    public clientStore: ClientStoreService) { }

  ngOnInit() {
    this.bindProjectData();
  }
async bindProjectData() {
    const userId = await this.clientStore.getItem('user');
    try {
      this.allProjects = await this.projectService.getProjects(userId);

      this.rows = this.allProjects.map(project => ({   // Error is thrown for this line
        projectId: project.id,
        projectName: project.name,
        clientName: project.client.name,
        clientLogo: project.client.logo,
        projectLocation: project.location.city + ', ' + project.location.state,
        contactPerson: project.client.contactPerson.firstName + ' ' + project.client.contactPerson.lastName,
        noOfUnits: project.noOfUnits,
        totalPrice: this.currencyPipe.transform(project.totalPrice.price, project.totalPrice.currency),
        createdOn: this.datePipe.transform(project.createdOn, 'short')
      }));
      this.isLoaded = true;

    } catch (err) {
      this.errorMessage = 'An error occured while fetching the projects!';
      this.toastr.error(this.errorMessage);
      console.error(err);
    }
  }

Spe c .ts

import { async, ComponentFixture, TestBed, fakeAsync, tick, inject } from '@angular/core/testing';
import { ProjectsListComponent } from './projects-list.component';
import { FormsModule, ReactiveFormsModule, FormBuilder } from '@angular/forms';

import { ToastrModule, ToastrService } from 'ngx-toastr';
// import { HttpClient, HttpClientModule } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { ProjectService } from 'src/app/shared/services/project.service';
import { ClientStoreService } from 'src/app/shared/services/client-store.service';

import { By } from '@angular/platform-browser';
import { Observable, of, throwError } from 'rxjs';
import { IProjectListItem } from './../../../shared/interfaces/project.interface';
import { RouterTestingModule } from '@angular/router/testing';
import { Location } from '@angular/common';
import { DebugElement } from '@angular/core';


class ProjectServiceStub {
    getProjects() {
    }
}

class ClientServiceStub {
    getItem() {
    }
}

class MockRouter {
    navigate(url: string) { return url; }
}

interface MockProjectItems {
    id: number;
    name: string;
    location: any;
    client: any;
    noOfUnits: number;
    totalPrice: any;
    createdBy: any;
    createdOn: Date;
    modifiedBy: any;
    modifiedOn: Date;
}

describe('Projects List Component', () => {
    let component: ProjectsListComponent;
    let fixture: ComponentFixture<ProjectsListComponent>;
    let spy: any;
    let projectService;
    let clientService;
    let projects: MockProjectItems[];

    const projectList: MockProjectItems[] = [
        {
            id: 1,
            name: 'abc',
            location: 'mys',
            client: 'tke',
            noOfUnits: 10,
            totalPrice: 10000,
            createdBy: 'xyz',
            createdOn: new Date(),
            modifiedBy: 'xyz',
            modifiedOn: new Date()
        }
    ];

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                ReactiveFormsModule,
                HttpClientTestingModule,
            ],
            declarations: [ProjectsListComponent],
            providers: [{ provide: ClientStoreService, useClass: ClientServiceStub }, { provide: ProjectService, useClass: ProjectServiceStub }]
        })
            .compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(ProjectsListComponent);
        component = fixture.componentInstance;
        component.allProjects = projects;
        projectService = TestBed.get(ProjectService);
        clientService = TestBed.get(ClientStoreService);
        fixture.detectChanges();
    });


        it('Service-2 : If project service is called', () => {
            spy = spyOn(projectService, 'getProjects').and.returnValue(of(projectList));
            component.bindProjectData();
            expect(spy).toHaveBeenCalled();
        });
});

Тестовый случай завершается с ошибкой «Невозможно прочитать карту свойств undefined». (allProjects varibale в файле component.ts) Пожалуйста, предложите способ заставить этот тестовый сценарий работать

...