TypeError: Cannot set properties of undefined (setting 'object')

TypeError: Cannot set properties of undefined (setting 'object')

我有一个函数,当调用它时从 ngbModal 打开一个模式,我已经导入了所有必要的东西并创建了一个 NgbModalRef 的模拟,但是当我进行单元测试时我得到这个错误“TypeError:无法设置属性未定义(设置 'object')”。

我在 Whosebug 上尝试了一个解决方案,但它并不完全有效,这是来源: Writing a unit test for ng-bootstrap modal (NgbModal) [Angular 6]

如何在我的测试中修复该错误?

我的函数

remove = (report) => {
        if (report.contents.length) {
            const modalRef = this.modalService.open(ConfirmModalComponent,
                {
                    scrollable: true,
                    windowClass: 'myCustomModalClass',
                });
            modalRef.componentInstance.object = 'Para borrar el informe "' + report.name + '" primero debe borrar los contenidos asociados.';
            modalRef.componentInstance.button = "Aceptar";
            modalRef.result.then((result) => {

            }).catch(() => {

            });
        } else {
            const modalRef = this.modalService.open(ConfirmModalComponent,
                {
                    scrollable: true,
                    windowClass: 'myCustomModalClass',
                });
            modalRef.componentInstance.object = report.name;
            modalRef.componentInstance.button = this.lang.get('delete');
            modalRef.result.then((result) => {
                if (result == 'accept') {
                    let idx = Object.keys(this.reports).filter(i => this.reports[i].id == report.id);
                    this.reports.splice(+idx[0], 1);
                    this.api.send('Reports', 'removeReport', { report: report })
                }
            }).catch(() => { });
        }
    }

我的规范文件:

import { NgbModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { Api, MenuService, FilterService, RoutingData } from 'is-common';
import { ReportsComponent } from './reports.component';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';
import { ConfirmModalComponent } from '../../components/confirm-modal/confirm-modal.component';

export class MockNgbModalRef {
    componentInstance: {
        object: undefined,
        button: undefined
    }
    result: Promise<any> = new Promise((resolve, reject) => resolve(true));
}

describe('ReportsComponent', () => {
let component: ReportsComponent;
    let fixture: ComponentFixture<ReportsComponent>;
    let api: Api;
    let httpMock: HttpTestingController;
    let menuService: MenuService;
    let filterService: FilterService;
    let routingData: RoutingData;
    let routerTest: RouterTestingModule;
    let ngbModal: NgbModal;
    let mockModalRef: MockNgbModalRef = new MockNgbModalRef();

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                HttpClientTestingModule,
                RouterTestingModule,
                CookieModule.forRoot(),
                NgbModule
            ],
            declarations: [
                ReportsComponent
            ],
            providers: [
                Api,
                CookieService,
                RoutingData,
                MenuService,
                FilterService,
                { provide: Router, useValue: routerMock },
                { provide: FilterSummaryPipe, useClass: FilterSummaryPipeMock }
            ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(ReportsComponent);
        component = fixture.componentInstance;
        ngbModal = TestBed.inject(NgbModal);
        api = TestBed.inject(Api);
        httpMock = TestBed.inject(HttpTestingController);
        menuService = TestBed.inject(MenuService);
        filterService = TestBed.inject(FilterService);
        routingData = TestBed.inject(RoutingData);
    });
describe('remove', () => {
        it('Should remove the report', () => {
            let report = { id:1, name: 'Prueba', date: "2021-09-23", contents: ['contenido de prueba'] }
            let spy1 = spyOn(ngbModal, 'open').and.returnValue(MockNgbModalRef as any);

            component.remove(report);

            expect(spy1).toHaveBeenCalled();
            expect(spy1).toHaveBeenCalledTimes(1);
            expect(spy1).toHaveBeenCalledWith(ConfirmModalComponent, {scrollable: true, windowClass: 'myCustomModalClass'});
        });
    });

});

由于 angular 使用打字稿,您需要提及您正在使用的变量的类型,因此无论您在何处使用箭头函数,请指定对象的类型。

对于 example:In 你的 ts 文件指定结果的类型也为过滤器

modalRef.result.then((result: any) => {
            if (result == 'accept') {
                let idx = Object.keys(this.reports).filter((i: any) => this.reports[i].id == report.id);
                this.reports.splice(+idx[0], 1);
                this.api.send('Reports', 'removeReport', { report: report })
            }
        }).catch(() => { });