Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unit-test that MatDialog is closed, by mat-dialog-close or otherwise

I have a simple component, which will be displayed as a dialog window by MatDialog. In the template of that component, one button is labelled with mat-dialog-close attribute, which should close the dialog window.

How can I unit-test that the dialog is indeed closed when clicking on the button? Moreover, mat-dialog-close can take an argument and pass it to whomever opened the dialog. How can I verify that the correct value is passed?

It's not about testing the MatDialog machinery, more about correctly attaching it to the component. From the test's POV I couldn't care less if the dialog was closed by the button with mat-dialog-close or by carefully set timeout that calls this.dialogRef.close(). In the latter case I could mock the injected dialogRef and spy on calling close, but using mat-dialog-close is much more convenient, so I'd like to stick to this.

Normally I'd use TestBed.createComponent to create components, maybe this would have to be changed somehow.

like image 647
Torinthiel Avatar asked Apr 02 '18 10:04

Torinthiel


People also ask

How do you test for afterClosed?

You can test Angular Material Dialog's afterClosed method this way: import { of } from 'rxjs'; spy on the dialog and return an observable for the afterClosed() method.

How do I cancel MatDialog?

By default, the escape key closes MatDialog .


1 Answers

I'm a bit late to the party, but here's how I did this. As mentioned in the comments above, a spy on the injected MatDialogRef is needed. The part that OP may have missed is that behind the scenes that will be called by material with the mat-dialog-close attribute AS WELL AS when this.dialogRef.close() is called manually from within the component.

My component only uses the following template:

<button mat-button mat-dialog-close>Cancel</button>

and the following test passes just fine:

it('should close the component if cancel is clicked', () => {
    mockDialogRef.close.calls.reset();
    page.cancelButton.click();
    expect(mockDialogRef.close).toHaveBeenCalled();
});

(I use a page class to define what is on the page for clarity when reading .spec files, as suggested in the Angular docs.)

This exact same test passes if instead I call a function and execute this.dialogRef.close().

While I am not testing a value passed, the OP did ask about that. Something like this should do the trick:

In the template:

<button mat-button [mat-dialog-close]="true">Cancel</button>

And now in the test:

it('should close the component and pass back correct data if cancel is clicked', () => {
    mockDialogRef.close.calls.reset();
    page.cancelButton.click();
    expect(mockDialogRef.close).toHaveBeenCalledWith(true);
});

I hope this helps.

like image 142
dmcgrandle Avatar answered Oct 25 '22 10:10

dmcgrandle