Failed: Can't resolve all parameters for MatDialogRef: (?, ?, ?). unit testing Angular project

╄→尐↘猪︶ㄣ 提交于 2019-12-01 03:22:07

When I was trying to test the dialog component I encountered the same issue. My solution is based on the dialog test in angular-material source code.

import { MyDialogComponent } from './mydialog.component';
import { async, TestBed, inject } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatDialog } from '@angular/material/dialog';
import { OverlayContainer } from '@angular/cdk/overlay';

describe('MyDialogComponent', () => {
  let dialog: MatDialog;
  let overlayContainer: OverlayContainer;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyDialogComponent],
      imports: [
        MatDialogModule,
      ]
    });

    TestBed.overrideModule(BrowserDynamicTestingModule, {
      set: {
        entryComponents: [MyDialogComponent]
      }
    });

    TestBed.compileComponents();
  }));

  beforeEach(inject([MatDialog, OverlayContainer],
    (d: MatDialog, oc: OverlayContainer) => {
      dialog = d;
      overlayContainer = oc;
    })
  );

  afterEach(() => {
    overlayContainer.ngOnDestroy();
  });

  it('should open a dialog with a component', () => {
    const dialogRef = dialog.open(MyDialogComponent, {
      data: { param: '1' }
    });

    // verify
    expect(dialogRef.componentInstance instanceof MyDialogComponent).toBe(true);
  });
});

I'm not sure this is the right approach though, still a beginner myself.

Phil

Depending on your needs, a more simple approach is injecting a mock MatDialog provider that has a jasmine spy for the close or open methods. For instance:

import { MyDialogComponent } from './mydialog.component';
import { async, TestBed, inject } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { MatDialog } from '@angular/material/dialog';

describe('MyDialogComponent', () => {
  const mockDialogRef = {
    close: jasmine.createSpy('close')
  };

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyDialogComponent],
      imports: [MatDialogModule],
      providers: [
        {
          provide: MatDialogRef,
          useValue: mockDialogRef
        }
      ]
    })
    .compileComponents();
  }));

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

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

  it('#onClosedeleteCustomer should close the dialog', () => {
    component.onClosedeleteCustomer();
    expect(mockDialogRef.close).toHaveBeenCalled();
  });
});

This gist is, don't inject the real instance of the MatDialog or MatDialogRef in your test. Inject a mock object instead with a jasmine spy that can tell you if a method has been called.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!