I have a function that when calling it opens a modal from ngbModal, I have imported everything necessary and also created a mock of NgbModalRef, but when I do the unit test I get this error "TypeError: Cannot set properties of undefined (setting 'object')".
I tried a solution on stackoverflow but it doesn't work completely, this is the source: Writing a unit test for ng-bootstrap modal (NgbModal) [Angular 6]
How can I fix that error in my test?
My function
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(() => { });
}
}
My spec file:
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'});
});
});
});
CodePudding user response:
Since angular uses typescript you need to mention the type of the variable that you're using, so wherever you are using arrow function specify the type of the object.
For example:In your ts file specify the type for result also for filter
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(() => { });