【问题标题】:How to mock a response from MatDialog sent from afterClosed in Angular unit tests?如何在 Angular 单元测试中模拟从 afterClosed 发送的 MatDialog 响应?
【发布时间】:2021-10-04 20:11:58
【问题描述】:

我正在尝试为 MatDialog 编写一些单元测试。我想要做的是模拟来自对话框的响应并测试它是否被组件正确处理。

在我的组件中,我应该从关闭的对话框中获得一个Map<string, any>,并将它们设置为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);
  }));

});

在我的规范文件中,我创建了一些 responseMock,我试图将其用作响应,但我的测试只是失败了:

Chrome Headless 91.0.4472.164 (Windows 10) 错误 afterAll 中抛出了一个错误 类型错误:无法读取未定义的属性“forEach”
Chrome 91.0.4472.164 (Windows 10) MyComponent 应该从 FAILED 对话框中获取数据 错误:预期 0 为 2。

如何在单元测试中模拟来自 MatDialog 的响应,以便MyComponent 正确处理?

【问题讨论】:

    标签: angular unit-testing jasmine mat-dialog


    【解决方案1】:

    在被测试的方法中,有一个针对响应数据的循环:response.data.forEach。根据模拟设置,response 的值将是const responseMock = new Map&lt;string, any&gt;();。它不包含 data 属性。要修复它,您可以将响应模拟更改为

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

    【讨论】:

    • 就是这样。谢谢,我没注意到:)
    猜你喜欢
    • 1970-01-01
    • 2021-09-14
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2018-11-24
    • 2021-09-18
    相关资源
    最近更新 更多