0

I'm trying to spy a call service to know if have been called after matdialog is closed.

But I have this error..

TypeError: Cannot read property 'close' of undefined

But if I not try to close the dialog, the code inside "afterClosed()" subscription, is never called

This is my Component method:

constructor(private service:CustomService,
        public dialog: MatDialog,
        private dialogRef:MatDialogRef<EditarGrupoDialogComponent, any>) {}

//[....]

modificar:void{

        //Open dialog to edit object
        this.dialogRef = this.dialog.open(EditarGrupoDialogComponent, {
            width: '80%',
            height: 'auto',
            disableClose: true,
            data: {
                groupToEdit: group
            }
        });

        //If close with modification, we send the mew version to service
        this.dialogRef.afterClosed().subscribe(
            resultados => {
                //If there are results
                if(resul){
                     //Peticion al servicio de historial para publicar modificacion
                    this.service.realiza(resul).subscribe(
                        resul => {
                            //RequestOk
                            // [...]
  
                        },
                        (err) => {
                          //error
                          this.error=true;

                        }
                    );

                }// ESLE.No results
            }
        );
    }

This is my spec.ts file:

describe('Test GComponent', () => {
    let component: GComponent;
    let fixture: ComponentFixture<GComponent>;
    const dialogMock = new MatDialogMock();

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [ GruposCComponent ],
            imports:[
                HttpClientTestingModule,
                MatDialogModule,
                NoopAnimationsModule
            ],
            providers: [
                { provide: CustomService, useClass: ServiceMock },
                { provide: MatDialogRef, useClass: MatDialogRefMock},
                { provide: MatDialog, useValue: dialogMock}
            ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA]
        })
        .compileComponents();
      });

    beforeEach(() => {
        fixture = TestBed.createComponent(GruposCComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });
    
    it('Clik at button, allow modify group in dialog, and save it afterClosed', ()=>{

        //Espiamos el metodo 'modificarGrupoGrupo'
        const spy1 = spyOn(component, 'modificar').and.callThrough();
        //Espiamos el open Mat dialog
        const spy2 = spyOn(component["dialog"], 'open');

        //Espiamos metodo que emite suscripcion de cierre de dialog
        const spy3= spyOn(component["dialogRef"],"afterClosed").and.returnValue(
            of({
                group: {
                    id: "1CESO",
                    refFrame: "B"
                }
            })
        );

        //Espiamos servicio de historial
        //Intervenimos injeccion del servicio
        const service = fixture.debugElement.injector.get(CustomService);
        //Espiamos el servicio para forzar retorno de error
        const spy4 =spyOn(service, 'realiza');


        //Actualice view
        fixture.detectChanges();

        //Click the button to edit/open dialog
        const botonEditar= fixture.debugElement.query(By.css('#but'));
        botonEditar.nativeElement.click();

        //Actualice view
        fixture.detectChanges();
        //Close dialog
        component["dialogRef"].close();
        //Actualice view
        fixture.detectChanges();


        expect(spy1).toHaveBeenCalled();
        expect(spy2).toHaveBeenCalled();
        expect(spy3).toHaveBeenCalled();

        expect(spy4.calls.count()).toBe(1);

    });
    
    
    
});

My mocks:


export class ServiceMock  {

    realiza(accion:Accion):Observable<boolean>{
        //Simulate ok
        return of(true);
    }
}

/** Mock of refDialog */
export class MatDialogRefMock {
    close():void{}

    afterClosed(): Observable<any>{
        return of(true);
    }
}

/** Mock del Dialog */
export class MatDialogMock {
    open() {
        return {afterClosed: () => of({
                group: {
                    id: "1CESO",
                    refFrame: "B"
                }
            }) };
    }
}

What could be wrong? I only need check that dialogs open when the button of the view is cliked, and when de dialog is closed and retuns the object, te service is called with the object information.

THANS YOU FOR THE HELP!!!

DavidB
  • 1
  • 3
  • Before this line `//Close dialog component["dialogRef"].close();` can you console.log `component['dialogRef']`? If it is undefined, this is the problem. – AliF50 Jul 02 '21 at 12:58
  • Thanks @AliF50, You are right the problem is that component["dialogRef"] is undefined... I supposed is because the value is assigned inside the method i am testing.. so how I can spy afterClosed() ?? – DavidB Jul 03 '21 at 18:05
  • Try changing this line ` { provide: MatDialogRef, useClass: MatDialogRefMock} ` to `{ provide: MatDialogRef, useValue: {} },`, then I think you should be good. – AliF50 Jul 03 '21 at 19:15
  • Thanks! But it didn't work. With the change I get the eror ```Error: : afterClosed() method does not exist``` – DavidB Jul 05 '21 at 06:43
  • Remove `spy3` and I think remove `component["dialogRef"].close();` line as well. – AliF50 Jul 05 '21 at 12:56
  • @AliF50 After your last suggestion, the ' expect(spy4.calls.count()).toBe(1);' fails because is never called (Error: Expected 0 to be 1.) Could the problem be at the 'MatDialogMock' Class? – DavidB Jul 05 '21 at 21:19
  • Put a console.log inside of the `.subscribe` and see if it traverses it. I am thinking the `if(results)` is blocking it. – AliF50 Jul 05 '21 at 22:35
  • That console.log() is never printed. But i puted andother just after open de dialog, and the this.dialogRef is undefined. – DavidB Jul 07 '21 at 06:53
  • The dialogMock has an `afterClosed` method that returns what is needed, I am not sure what the issue could be. – AliF50 Jul 07 '21 at 12:39

1 Answers1

0

Finally I found the solution in another question in StackOverflow

https://stackoverflow.com/a/63270874/16364532

DavidB
  • 1
  • 3