Модульный тест для отправки реактивных форм в Angular в Jest

avatar
pranami
9 августа 2021 в 04:28
68
0
0

В моем файле .ts есть функция, которая используется для отправки данных формы.

Мой файл .html:

    <form id="alertshareform" autocomplete="off" [formGroup]="alertshareform" (ngSubmit)="submitalertsharemodal()">

</form>

Мой файл .ts с функцией:

submitalertsharemodal() {

    if (this.alertshareform.valid) {
      this.isSharebuttonClicked = true;
      let tableHeadername = '';
      let columnwidth: string[] = [];
      tableHeadername = this.alertsharemodaldata?.tab;
      if (this.alertsharemodaldata?.tab === 'DeviceSearch') {
        const tabName = 'Device Search';
        const minwidthval = (100 / this.alertsharemodaldata?.hiddencolumns?.length) + '%';
        for ( let i = 0; i < this.alertsharemodaldata?.hiddencolumns?.length; i++) {
          columnwidth.push(minwidthval);
        }
        tableHeadername = tabName + ' - ' + this.alertsharemodaldata?.deviceType;
      } else if ( this.alertsharemodaldata?.tab === 'History') {
        columnwidth = ['7%', '10%', '50%', '10%', '7%', '10%', '6%'];
      } else if (this.alertsharemodaldata?.tab === 'Settings') {
        columnwidth = ['50%', '10%', '10%', '10%', '10%', '10%'];
      } else if (this.alertsharemodaldata?.tab === 'Active') {
        columnwidth = ['15%', '35%', '10%', '10%', '8%', '15%'];
      }
      const tableheader = this.alertsharemodaldata?.hiddencolumns.map((e) => {
        const obj = {text: e.header, style: 'tableheader'};
        return obj;
      });
      const tablefield = this.alertsharemodaldata?.hiddencolumns.map(e => e.field);
      this.tableheaderarr = tableheader;
      this.tablefieldarr = tablefield;
      let tablebody : any[] = [];
      const bodyarr: any[] = [];
      bodyarr.push(tableheader);
      const replacer = (_key, value) => value === null ? 'N/A' : value;
      tablebody = this.alertsharemodaldata?.tabledata.map(e => {
        const arr: any[] = [];
        for (const field of tablefield) {
          const obj = {text: '', style: 'tablebody'};
          if (e[field] === undefined || e[field] === -1) {
            obj.text = 'N/A';
            arr.push(obj);
          } else if ('Severity' === field) {
            obj.text = JSON.stringify(this.severity[e[field]], replacer);
            arr.push(obj);
          } else if ('TimeStamp' === field) {
            obj.text = JSON.parse(JSON.stringify(moment(e[field]).format('MMM Do YYYY , hh:mm:ss A'), replacer));
            arr.push(obj);
          } else if ('SystemClearedTimeStamp' === field && typeof e[field] === 'number') {
            obj.text = JSON.parse(JSON.stringify(moment(e[field]).format('MMM Do YYYY , hh:mm:ss A'), replacer));
            arr.push(obj);
          } else if ('IsEnabled' === field) {
            obj.text = JSON.parse(JSON.stringify(this.isenabled[e[field]], replacer));
            arr.push(obj);
          } else {
            obj.text = e[field];
            arr.push(obj);
          }
        }
        bodyarr.push(arr);
        return arr;
      });
      this.tablebodyarr = tablebody;

      const d = new Date();
      const filename = tableHeadername?.replace(new RegExp(' ', 'g'), '') + '_' + d.getFullYear() + '' + d.getMonth()
        + '' + d.getDate() + '_' + Math.floor(d.getTime() / 1000) + '_' + 'username';
      const docdefinition = {
        header: {
          margin: 0,
          columns: [
            {
              image: environment.pdfciscolog,
              width: 85,
              height: 65
            },
            {text: 'Real Time  Monitoring Tool', style: 'header'},
            {text: 'For Cisco Unified Communications Solutions', style: 'subheader'},
            {text: '' + filename + '', style: 'filetitle'}
          ]
        },
        content: [
          {text: ' ' + tableHeadername + ' ', style: 'chartheadertext'},
          {
            table: {
              // headers are automatically repeated if the table spans over multiple pages
              // you can declare how many rows should be treated as headers
              headerRows: 1,
              widths: columnwidth,
              body: bodyarr
            }
          }
        ],
        footer: (currentPage, pageCount) => {
          return currentPage.toString() + ' of ' + pageCount;
        },
        pageSize: 'A3',
        pageOrientation: 'landscape',
        pageMargins: [40, 80, 40, 40],
        styles: {
          header: {
            fontSize: 8,
            bold: true,
            alignment: 'left',
            marginTop: 22
          },
          subheader: {
            fontSize: 7,
            alignment: 'left',
            marginLeft: -368,
            marginTop: 30
          },
          filetitle: {
            fontSize: 8,
            alignment: 'left',
            marginTop: 30,
            marginLeft: -50
          },
          chartheadertext: {
            fontSize: 12,
            marginTop: 20,
            marginBottom: 20,
            alignment: 'center'
          },
          tableheader: {
            fillColor: 'gray',
            color: 'white',
            fontSize: 12,
            fontFamily: 'CiscoSansTTRegular'
          },
          tablebody: {
            fontSize: 11,
            fontFamily: 'CiscoSansTTRegular'
          },
          footer: {
            alignment: 'center',
            fontSize: '8',
            color: '#ffffff',
          }
        }
      };
      pdfMake.vfs = pdfFonts.pdfMake.vfs;

      const pdfGenerator = pdfMake.createPdf(docdefinition);
      if ((this.alertshareform.value.method === 'download')) {
        if (this.alertshareform.value.filetype[0]) {
          pdfGenerator.download(filename + '.pdf');
        }
        if (this.alertshareform.value.filetype[1]) {
          this.generatecsvdata(true, filename);
        }
      }
      if ((this.alertshareform.value.method === 'email')) {
        this.loadingpdf = true;
        const emails = this.alertshareform.value.alertshareemailid.split(/[/,;]+/);
        const formJson = {
          toAddresses: emails,
          subject: this.alertshareform.value.subject,
          content: this.alertshareform.value.message,
          pdfFileData: null,
          csvFileData: {},
          fieldName: this.alertsharemodaldata.tab,
          tabName: this.alertsharemodaldata.tab,
          userName: 'username'
        };
        pdfGenerator.getBase64((data) => {
          const csvdata = this.generatecsvdata(false, '');
          if (this.alertshareform.value.filetype[1]) {
            formJson.csvFileData[this.alertsharemodaldata.tab] = csvdata;
          } else {
            formJson.csvFileData[this.alertsharemodaldata.tab] = null;
          }
          if (this.alertshareform.value.filetype[0]) {
            formJson.pdfFileData = data;
          }
          const jsostr = JSON.stringify(formJson);
          const jsonbody = JSON.parse(jsostr);
          this.apiService.sendEmail(jsonbody).subscribe(
            (response:any) => {
              const value = response.Response;
              const value1 = value.toString().split(':');
              const value2 = value1[0].trim();
              if (value2 === 'Success') {
                this.alertService.success('Email Sent Successfully', '', {
                  ariaLabel: 'Close Alert',
                  orderNewest: false,
                  onHide: () => console.info('onHide info'),

                });
                this.close();
              } else {
                this.alertService.error('Error Occured while sending email', '', {
                  ariaLabel: 'Close Alert',
                  orderNewest: false,
                  onHide: () => console.info('onHide info'),

                });

              }

            }
          );
        });

      }
      this.isSharebuttonClicked = false;
    }
    this.close();
  }

Я хочу написать модульный тест для этой функции.

Я пробовал это:

it('should submit alert data', () => {
    

    jest.spyOn(component, 'submitalertsharemodal');
    component.alertshareform.valid = true;
    component.submitalertsharemodal();
    expect(component.alertshareform.valid).toBeTruthy();
  //  expect(component.submitalertsharemodal).toHaveBeenCalled();
  });

Но я получаю эту ошибку:

enter image description here

Как решить эту проблему?

Изменить: Мой полный файл .spec.ts:

import { waitForAsync, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CommonTestUtilsModule, createComponent, Page, provideMockObject } from '@webex/common/test-utils';
import { CommonUiMomentumChModule, ModalRef } from '@webex/common/ui/momentum-ch';
import { ActivatedRoute } from '@angular/router';
import {AlertService} from '@webex/common/ui/momentum-ch';
import { BehaviorSubject } from 'rxjs';
import {ApiService} from '@webex/atlas/cloud-connected-uc/operations/data-access';
import { AlertcentralSharemodalComponent } from './alertcentral-sharemodal.component';
import { CUSTOM_ELEMENTS_SCHEMA, ElementRef, NO_ERRORS_SCHEMA } from '@angular/core';
import { By } from '@angular/platform-browser';

const MockApiService = {
  sendEmail: jest.fn(),
};


class AlertcentralSharemodalPage extends Page<AlertcentralSharemodalComponent> {
  modalRef: ModalRef;

  get anchorTag() {
    return this.elementQueryAll('a');
  }


  constructor(fixture: ComponentFixture<AlertcentralSharemodalComponent>) {
    super(fixture);
    this.modalRef = this.inject(ModalRef);
     this.modalRef.data = { tab: 'Test',
     tabledata: {
      'Name': 'Name',
      'Status': 'Status',
      'Node': 'Node',
      'IP Address': 'IpAddress',
      'IPv6 Address': 'Ipv6Address',
      'Login User ID': 'LoginUserId',
      'Description': 'Description',
      'Status Reason': 'StatusReason',
      'Timestamp': 'TimeStamp',
      'Directory Number': 'DirectoryNumber',
      'Active Load Id': 'ActiveLoadId',
      'Model': 'Model',
      'Protocol': 'Protocol',
      '% of Service': 'ServicePercentage',
      'Duration': 'Duration'
      },
   };
  }
}


describe('AlertCentralShareModalComponent', () => {
  let component: AlertcentralSharemodalComponent;
  let fixture: ComponentFixture<AlertcentralSharemodalComponent>;
  let page: AlertcentralSharemodalPage;
  const formBuilder: FormBuilder = new FormBuilder();
  let modalRef: jest.Mocked<any>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [ AlertcentralSharemodalComponent ],
      providers: [
        provideMockObject(ActivatedRoute),
        provideMockObject(AlertService),
        provideMockObject(ModalRef),
        {
          provide: FormBuilder,
          useValue: formBuilder
        },
        {
          provide: ApiService,
          useValue: MockApiService
        },

    ],
      imports: [
          CommonTestUtilsModule,
          CommonUiMomentumChModule,
          ReactiveFormsModule,
          FormsModule,
          RouterTestingModule,
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    .compileComponents();
  }));



  beforeEach(() => {
    // fixture = TestBed.createComponent(DeviceSearchFilterComponent);
    // component = fixture.componentInstance;
    ({ fixture, page } = createComponent(AlertcentralSharemodalComponent, AlertcentralSharemodalPage));
    component = fixture.componentInstance;
    component.tableheaderarr = ['a', 'b'];
    component.alertshareform.valid = true;

  // component.tablebodyarr = ['body1', 'body2'];
    fixture.detectChanges();
  });

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

  it('should set the validators on email selection', () => {
    jest.spyOn(component, 'onMethodChange');
    component.alertshareform.controls['method'].setValue('email');
    component.onMethodChange();
    component.alertshareform.value = 'email';
    component.alertshareform.updateValueAndValidity();
    fixture.detectChanges();
    expect(component.onMethodChange).toHaveBeenCalled();
    expect(component.alertshareform.controls['method']).toBeTruthy();
  });

  it('should clear the validators', () => {
    component.alertshareform.clearAsyncValidators();
    component.alertshareform.clearValidators();
    jest.spyOn(component, 'onMethodChange');
    component.alertshareform.controls['method'].setValue('test');
    component.onMethodChange();
    component.alertshareform.clearValidators();
    expect(component.onMethodChange).toHaveBeenCalled();
    // expect(component.alertshareform.clearValidators).toHaveBeenCalled();
  });

  it('should submit alert data', () => {
    // jest.spyOn(component, 'submitalertsharemodal');

    // jest.spyOn(component, 'submitalertsharemodal');
    // component.submitalertsharemodal();
    // fixture.detectChanges();


    jest.spyOn(component, 'submitalertsharemodal');
    // component.alertshareform.valid = true;
    component.submitalertsharemodal();
    fixture.detectChanges();
    expect(component.alertshareform.valid).toBeTruthy();
    expect(component.isSharebuttonClicked).toBeTruthy();
    // expect(component.submitalertsharemodal).toHaveBeenCalled();
  })

//   it('should call onSubmit method', () => {

//     let el = fixture.debugElement.query(By.css('button')).nativeElement;
//     el.click();
//     expect(component.alertshareform).toHaveBeenCalledTimes(1);
// });

  it('generate csv data', () => {
    jest.spyOn(component, 'generatecsvdata');
    component.generatecsvdata(true, 'testfile');
    expect(component.generatecsvdata).toHaveBeenCalled();
  });

  it('coverts json to csv data', () => {
    jest.spyOn(component, 'convertJsontocsv');
    component.convertJsontocsv();
    expect(component.convertJsontocsv).toHaveBeenCalled();
  });

  it('close the modal', () => {
    jest.spyOn(component, 'close');
    component.close();
    expect(component.close).toHaveBeenCalled()
  })

  it('check form data', () => {
    component.alertshareform.controls['method'].setValue('email');

  })
});
Источник
Tejeshree
9 августа 2021 в 05:45
0

Объявили ли вы какое-либо значение для component.alertshareform в блоке beforeEach или где-либо еще в вашем пакете? Будет полезно, если вы поделитесь

pranami
9 августа 2021 в 06:09
0

@Tejeshree Я добавил полный файл spec в редактирование выше. Пожалуйста, посмотрите.

jonrsharpe
9 августа 2021 в 06:59
1

Вам нужно сделать форму действительной, заполнив ее. Также вы не должны шпионить за частями того, что вы должны тестировать, особенно если вы собираетесь провести «тест», который вызывает шпиона и утверждает, что шпиона вызвали.

Ответы (0)