Unit test Angular Material Dialog - How to include MAT_DIALOG_DATA

25,244

Solution 1

Try this:

describe('Confirmation Dialog Component', () => {
    
  const model: ConfirmationDialogModel = {
    ActionButton: 'Delete',
    SupportingText: 'Are you sure?',
  };
    
  let component: ConfirmationDialogComponent;
  let fixture: ComponentFixture<ConfirmationDialogComponent>;
    
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        ConfirmationDialogComponent
      ],
      imports: [
        MatButtonModule,
        MatDialogModule
      ],
      providers: [
        {
          // I was expecting this will pass the desired value
          provide: MAT_DIALOG_DATA,
          useValue: model
        }
      ]
    })
      .compileComponents();
            
  }));
    
        
  beforeEach(() => {
    fixture = TestBed.createComponent(ConfirmationDialogComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
    
  it('should be created', async(() => {
    expect(component).toBeTruthy();
  }));

  it('should close dialog when close button clicked', fakeAsync(() => {
    component.onCloseButtonClicked(0);
    fixture.detectChanges();
    tick();
    expect(mockMainDialogRef.close.calls.count()).toBe(1, 'dialog closed');
  }));
});

Solution 2

Here's an example of how to inject MAT_DIALOG_DATA in a unit test:

 import { async, ComponentFixture, TestBed } from '@angular/core/testing';
 import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';

 import { ConfirmDialogComponent } from './confirm-dialog.component';

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

   beforeEach(async(() => {
     TestBed.configureTestingModule({
       declarations: [ ConfirmDialogComponent ],
       imports: [ MatDialogModule ], // add here
       providers: [
        { provide: MAT_DIALOG_DATA, useValue: {} } // add here
      ],
    })
    .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});
Share:
25,244
Erik
Author by

Erik

Updated on August 27, 2020

Comments

  • Erik
    Erik almost 4 years

    I am trying to unit test this material dialog to test if the template is rendering the right injected object. The component works fine when used properly

    Component - The Dialog

    export class ConfirmationDialogComponent {
    
      constructor(@Inject(MAT_DIALOG_DATA) private dialogModel: ConfirmationDialogModel) {}
    }
    

    Dialog Template

    <h1 mat-dialog-title *ngIf="dialogModel.Title">{{dialogModel.Title}}</h1>
    <div mat-dialog-content>
      {{dialogModel.SupportingText}}
    </div>
    <div mat-dialog-actions>
      <button mat-button color="primary" [mat-dialog-close]="false">Cancel</button>
      <button mat-raised-button color="primary"[mat-dialog-close]="true" cdkFocusInitial>{{dialogModel.ActionButton}}</button>
    </div>
    

    Model - What is getting injected

    export interface ConfirmationDialogModel {
      Title?: string;
      SupportingText: string;
      ActionButton: string;
    }
    

    Unit Test - Where I get the issue

    describe('Confirmation Dialog Component', () => {
    
      const model: ConfirmationDialogModel = {
        ActionButton: 'Delete',
        SupportingText: 'Are you sure?',
      };
    
      let component: ConfirmationDialogComponent;
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          declarations: [
            ConfirmationDialogComponent
          ],
          imports: [
            MatButtonModule,
            MatDialogModule
          ],
          providers: [
            {
              // I was expecting this will pass the desired value
              provide: MAT_DIALOG_DATA,
              useValue: model
            }
          ]
        });
    
        component = TestBed.get(ConfirmationDialogComponent);
      }));
    
      it('should be created', async(() => {
        expect(component).toBeTruthy();
      }));
    });
    

    Karma error

    Karma Error Screenshot

  • Netanel Draiman
    Netanel Draiman over 5 years
    In Addition, if you're using MatDialogRef in your component you need to include in in the providers array. Example: JavaScript providers: [{ provide: MatDialogRef, useValue: { close: (dialogResult: any) => { } } }] source
  • utdev
    utdev almost 4 years
    How would I need to test something like should be closed?
  • Indrakumara
    Indrakumara almost 4 years
    @utdev I have updated the answer with the should closed unit test
  • Elias
    Elias over 2 years
    @Indrakumara you indeed have update the answer, although it is not evident where mockMainDialogRef is coming from. How does one obtain the ref?