So I have a MatDialog Box which on close sends some form values. I then dispatch an action in the afterClosed method provided by MatDialogRef.
This works quite alright when I manually test it. But while unit testing, the dispatch isn't called and my test fails.
My Code that runs when opening the dialog & dispatches the action when closed.
openAddUserDialog() {
this.addUserDialog = this.dialog.open(AddUserDialogComponent, {
width: 'max-content',
height: 'max-content',
minWidth: '35vw',
minHeight: '20vh',
autoFocus: false
});
this.addUserDialog.afterClosed().subscribe(result => {
console.log(result);
this.store.dispatch({type: UserActions.ActionTypes.TryAddUser, payload: result.value});
});
}
The Mock for MatDialog
export class MatDialogMock {
open() {
return {
afterClosed: () => of(initialValue)
};
}
}
TestBed Config
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MaterialModule, ReactiveFormsModule, BrowserAnimationsModule],
declarations: [ UserManagementDialogComponent ],
providers: [{provide: MatDialog, useClass: MatDialogMock}, provideMockStore({initialState})]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(UserManagementDialogComponent);
component = fixture.componentInstance;
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
dialog = TestBed.get(MatDialog);
fixture.detectChanges();
});
And the test that should pass
it('should dispatch an action when the form is submitted', fakeAsync(() => {
spyOn(dialog, 'open').and.callThrough();
const dialogRef = dialog.open();
dialogRef.afterClosed().subscribe(result => {
console.log('verbrberbhyn', result);
expect(result).toEqual(initialValue);
tick();
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith({
type: UserAtions.ActionTypes.TryAddUser,
payload: initialValue
});
});
}));
Found out why I couldn't pass the test case.
afterClosed()
gets called after the dialog is closed. So all I had to do was call dialog.close()
before subscribing to afterClosed()
So at the end my test function looks like:
it('should dispatch an action when the form is submitted', () => {
spyOn(dialog, 'open').and.callThrough();
component.openAddUserDialog();
dialog.close();
component.addUserDialog.afterClosed().subscribe(result => {
expect(result.value).toEqual(initialValue);
expect(store.dispatch).toHaveBeenCalledTimes(1);
expect(store.dispatch).toHaveBeenCalledWith({
type: UserAtions.ActionTypes.TryAddUser,
payload: result.value
});
});
});
And I also updated the Mock
export class MatDialogMock {
open() {
return {
afterClosed: () => of({value: initialValue})
};
}
close() {}
}
So as to call close()
on the mock dialog and also updated afterClosed()
as the action's payload is stored in value property:
this.addUserDialog.afterClosed().subscribe(result => {
console.log(result);
this.store.dispatch({type: UserActions.ActionTypes.TryAddUser, payload: result.value});
});