Angular / Jasmine:没有提供叠加层的提供商!还有如何测试材质对话框

时间:2020-09-26 23:38:25

标签: angular jasmine

我正在尝试测试有角材质对话框,特别是我想测试在关闭对话框时它是否修改了路径。为此,我不想模拟/取消对话框(我不认为吗?),因为我希望它运行执行重新路由的实际.subscribe方法。

在我的实际对话框中出现两个错误:

this.dialogRef.afterClosed is not a function

login-dialog-component.spec.ts

describe('LoginDialogComponent', () => {
  let component: LoginDialogComponent;
  let fixture: ComponentFixture<LoginDialogComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [LoginDialogComponent],
      imports: [
        RouterTestingModule.withRoutes([]),
        MatDialogModule
      ],
      providers: [
        {provide: MatDialog},
        {provide: MAT_DIALOG_DATA, useValue: {}},
        {provide: MatDialogRef, useValue: {}},
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

我遇到的第二个错误是对打开对话框的组件的测试。它报告:

NullInjectorError: R3InjectorError(DynamicTestModule)[MatDialog -> Overlay -> Overlay]: 
  NullInjectorError: No provider for Overlay!

打开对话框的组件测试: login.component.spec.ts

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ LoginComponent ],
      providers: [
        { provide: MatDialog },
        { provide: MAT_DIALOG_DATA, useValue: {} },
        { provide: MatDialogRef, useValue: {}}
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

LoginComponent本身并不需要任何测试,但是如上所述,它给了我“没有覆盖程序的提供者”的原因,大概是因为构造函数是:

 constructor(
    private dialog: MatDialog
  ) { }

LoginComponent然后打开LoginDialog。

我要在LoginDialog中测试的代码是:

 ngOnInit(): void {
    this.dialogRef.afterClosed().subscribe(_ =>
      this.router.navigate(['', {outlets: {login: null}}])
    );
  }

我想确保在对话框关闭时路由器确实可以离开。

所以我的问题是

  1. 如何传递真实的对话框参考LoginDialog的构造函数?
  2. 如何摆脱“重叠式广告的否”提供程序?

顺便说一句,如果我改变

{ provide: MatDialogRef, useValue {})

收件人:

{ provide: MatDialogRef }

(所以我想尝试传递一个实际的MatDialogRef)

错误发生于

this.dialogRef.afterClosed is not a function

收件人:

Can't resolve all parameters for MatDialogRef: (?, ?).

谢谢。

1 个答案:

答案 0 :(得分:1)

尝试:

login-dialog-component.spec.ts中,删除整个providers数组,因为我们不应该模拟MatDialog的内部工作原理,而应将MatDialogModule保留在imports中。 / p>

login.component.spec.ts的{​​{1}}的{​​{1}}数组中添加MatDialogModule,然后如前所述删除imports数组。