最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to unit test MatDialog (Angular Material) the correct way? - Stack Overflow

programmeradmin2浏览0评论

I am busy wit unit testing. And I have a Matdialog form Angular material.

I tried to test this two functions:

openEcheqSelectorDialog() {
    this.dialog.open(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

  openSchemaSelectorDialog() {
    this.dialog.open(SchemaSendDialogComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

And this is the plete ponent:


export class DetailComponent implements OnInit {
  participant: ParticipantInfoDTO;

  constructor(private dialog: MatDialog, route: ActivatedRoute) {
    this.participant = route.snapshot.data['participant'];
  }

  ngOnInit() {
  }

  openEcheqSelectorDialog() {
    this.dialog.open(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

  openSchemaSelectorDialog() {
    this.dialog.open(SchemaSendDialogComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }
}


But if I do this in the unit test:


import { async, TestBed, ComponentFixture } from '@angular/core/testing';
import { ParticipantModule } from '../../participant.module';
import { ActivatedRoute } from '@angular/router';
import { PARTICIPANT_INFO_DTO } from 'src/app/shared/stubs/participant-info-dto.stub';
import { MatDialog } from '@angular/material/dialog';
import { I18nStub } from 'src/app/shared/stubs/i18n-stub';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { DetailComponent } from './detailponent';
import { RouterTestingModule } from '@angular/router/testing';

describe('DetailComponent', () => {

  let ponent: DetailComponent;
  let fixture: ComponentFixture<DetailComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        ParticipantModule,
        RouterTestingModule
      ],
      providers: [
        MatDialog,
        { provide: ActivatedRoute, useValue: {
          snapshot: {
            data: {
              participant: PARTICIPANT_INFO_DTO[0]
            }
          }
        }},
        { provide: I18n, useValue: I18nStub }
      ]
    })pileComponents().then( () => {
      fixture = TestBed.createComponent(DetailComponent);
      ponent = fixtureponentInstance;
      fixture.detectChanges();
    });
  }));

  it('should create the DetailComponent', () => {
    fixture.detectChanges();
    expect(ponent).toBeTruthy();
  });

  it('should open the EcheqSelectorComponent in a MatDialog', () => {
    ponent.openEcheqSelectorDialog();
  });

  it('Should open the SchemaSelectorDialog in a MatDialog' , () => {
    ponent.openSchemaSelectorDialog();
  });

});


Then in the code coverage of jasmine karma. Everything seems been covered- it says 100%. But I don't think this is the correct way to do the unit tests.

So my question is: Is the correct?

Or what I have to improve?

Thank you

This is the template:

<div class="header">
  <h1 class="heading list-heading"><span i18n>Participant</span> - {{ participant.fullName }}</h1>
</div>
<div class="body pulled-up">
  <mat-card class="card-spacing">
    <mat-card-header>
      <mat-card-title i18n>Actions</mat-card-title>
    </mat-card-header>
    <mat-card-content>
      <button mat-raised-button class="button-spacing" (click)="openEcheqSelectorDialog()" i18n>Send echeq</button>
      <button mat-raised-button class="button-spacing" (click)="openSchemaSelectorDialog()" i18n>Send schema</button>
    </mat-card-content>
  </mat-card>
  <mat-card class="card-spacing">
      <mat-card-header>
        <mat-card-title i18n>Overviews</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <button mat-raised-button class="button-spacing" routerLink="echeq" i18n>Echeqs</button>
        <button mat-raised-button class="button-spacing" routerLink="schema" i18n>Schemas</button>
        <button mat-raised-button class="button-spacing" routerLink="qrcode" i18n>Qrcode scans</button>
      </mat-card-content>
    </mat-card>
</div>

I am busy wit unit testing. And I have a Matdialog form Angular material.

I tried to test this two functions:

openEcheqSelectorDialog() {
    this.dialog.open(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

  openSchemaSelectorDialog() {
    this.dialog.open(SchemaSendDialogComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

And this is the plete ponent:


export class DetailComponent implements OnInit {
  participant: ParticipantInfoDTO;

  constructor(private dialog: MatDialog, route: ActivatedRoute) {
    this.participant = route.snapshot.data['participant'];
  }

  ngOnInit() {
  }

  openEcheqSelectorDialog() {
    this.dialog.open(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }

  openSchemaSelectorDialog() {
    this.dialog.open(SchemaSendDialogComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: this.participant
      }
    });
  }
}


But if I do this in the unit test:


import { async, TestBed, ComponentFixture } from '@angular/core/testing';
import { ParticipantModule } from '../../participant.module';
import { ActivatedRoute } from '@angular/router';
import { PARTICIPANT_INFO_DTO } from 'src/app/shared/stubs/participant-info-dto.stub';
import { MatDialog } from '@angular/material/dialog';
import { I18nStub } from 'src/app/shared/stubs/i18n-stub';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { DetailComponent } from './detail.ponent';
import { RouterTestingModule } from '@angular/router/testing';

describe('DetailComponent', () => {

  let ponent: DetailComponent;
  let fixture: ComponentFixture<DetailComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        ParticipantModule,
        RouterTestingModule
      ],
      providers: [
        MatDialog,
        { provide: ActivatedRoute, useValue: {
          snapshot: {
            data: {
              participant: PARTICIPANT_INFO_DTO[0]
            }
          }
        }},
        { provide: I18n, useValue: I18nStub }
      ]
    }).pileComponents().then( () => {
      fixture = TestBed.createComponent(DetailComponent);
      ponent = fixture.ponentInstance;
      fixture.detectChanges();
    });
  }));

  it('should create the DetailComponent', () => {
    fixture.detectChanges();
    expect(ponent).toBeTruthy();
  });

  it('should open the EcheqSelectorComponent in a MatDialog', () => {
    ponent.openEcheqSelectorDialog();
  });

  it('Should open the SchemaSelectorDialog in a MatDialog' , () => {
    ponent.openSchemaSelectorDialog();
  });

});


Then in the code coverage of jasmine karma. Everything seems been covered- it says 100%. But I don't think this is the correct way to do the unit tests.

So my question is: Is the correct?

Or what I have to improve?

Thank you

This is the template:

<div class="header">
  <h1 class="heading list-heading"><span i18n>Participant</span> - {{ participant.fullName }}</h1>
</div>
<div class="body pulled-up">
  <mat-card class="card-spacing">
    <mat-card-header>
      <mat-card-title i18n>Actions</mat-card-title>
    </mat-card-header>
    <mat-card-content>
      <button mat-raised-button class="button-spacing" (click)="openEcheqSelectorDialog()" i18n>Send echeq</button>
      <button mat-raised-button class="button-spacing" (click)="openSchemaSelectorDialog()" i18n>Send schema</button>
    </mat-card-content>
  </mat-card>
  <mat-card class="card-spacing">
      <mat-card-header>
        <mat-card-title i18n>Overviews</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <button mat-raised-button class="button-spacing" routerLink="echeq" i18n>Echeqs</button>
        <button mat-raised-button class="button-spacing" routerLink="schema" i18n>Schemas</button>
        <button mat-raised-button class="button-spacing" routerLink="qrcode" i18n>Qrcode scans</button>
      </mat-card-content>
    </mat-card>
</div>

Share Improve this question edited Nov 27, 2019 at 1:42 Shashank Vivek 17.5k9 gold badges69 silver badges110 bronze badges asked Nov 25, 2019 at 15:36 user12296049user12296049 2
  • Somebody any advice? Thank you – user12296049 Commented Nov 25, 2019 at 15:50
  • you are not testing the second and third cases. You must expect something. – Ricardo Ferreira Commented Nov 25, 2019 at 19:39
Add a ment  | 

1 Answer 1

Reset to default 2

I can give you some hint to work on this. You need to create a spy and put expect on it. Something like:

make dialog service public so that you can easily put spy on it

constructor(public dialog: MatDialog, route: ActivatedRoute) {
    this.participant = route.snapshot.data['participant'];
  }

spec.ts

  it('should open the EcheqSelectorComponent in a MatDialog', () => {
    spyOn(ponent.dialog,'open').and.callThrough();
    ponent.openEcheqSelectorDialog();
    expect(ponent.dialog.open).toHaveBeenCalledWith(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: ponent.participant
      }
    });
  });

  it('Should open the SchemaSelectorDialog in a MatDialog' , () => {
    spyOn(ponent.dialog,'open').and.callThrough();
    ponent.openSchemaSelectorDialog();
    expect(ponent.dialog.open).toHaveBeenCalledWith(SchemaSendDialogComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: ponent.participant
      }
    });
  });

Let me know if this worked for you or if you are getting error.

发布评论

评论列表(0)

  1. 暂无评论