Kamil
Kamil

Reputation: 592

How to mock a response from MatDialog sent from afterClosed in Angular unit tests?

I am trying to write some unit tests for MatDialog. What I am trying to do is to mock the response from the dialog and test, if it was correctly handled by the component.

In my component, I should get a Map<string, any> from the closed dialog and set them into myData Map.

my.component.ts

export class MyComponent {

  public myData = new Map<string, any>();

  constructor(public dialog: MatDialog) { }

  public openDialog(): void {
    const dialogRef = this.dialog.open(LoadDataComponent);
    dialogRef.afterClosed().subscribe(response => {
        response.data.forEach(item => {
            this.myData.set(item.id, item);
        });
    });
  }
}

my.component.spec.ts

describe('MyComponent', () => {
  let component: MyComponent;
  let fixture: ComponentFixture<MyComponent>;
  const responseMock = new Map<string, any>();
  
  class DialogMock {
    open(): any {
      return {
        afterClosed: () => of(responseMock)
      };
    }
  }

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [
        MyComponent
      ],
      providers: [
        { provide: MatDialog, useClass: DialogMock },
      ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    component.myData = new Map<string, any>();
    fixture.detectChanges();
    responseMock.set('test', {value: 'test'});
    responseMock.set('test2', {value: 'test2'});
  });



  it('should get data from dialog', fakeAsync(() => {
  
    spyOn(component.dialog, 'open').and.returnValue({
        afterClosed: () => of(responseMock)
    } as MatDialogRef<typeof component>);

    component.openDialog();
    expect(component.myData.size).toBe(2);
  }));

});

In my spec file I have created some responseMock and I am trying to use it as a response but my test is simply failing:

Chrome Headless 91.0.4472.164 (Windows 10) ERROR An error was thrown in afterAll TypeError: Cannot read property 'forEach' of undefined
Chrome 91.0.4472.164 (Windows 10) MyComponent should get data from dialog FAILED Error: Expected 0 to be 2.

How can I mock a response from MatDialog in my unit test so it will be correctly handled by MyComponent?

Upvotes: 1

Views: 1572

Answers (1)

IAfanasov
IAfanasov

Reputation: 4993

In the method under the test, there is a loop against response data: response.data.forEach. According to mock setup, the value if the response would be const responseMock = new Map<string, any>();. It doesn't contain the data property. To fix it you might change the response mock to

const responseMock = {data: new Map<string, any>()};

Upvotes: 2

Related Questions