Javascript 如何以正确的方式对MatDialog(角材料)进行单元测试?

Javascript 如何以正确的方式对MatDialog(角材料)进行单元测试?,javascript,angular,unit-testing,karma-jasmine,istanbul,Javascript,Angular,Unit Testing,Karma Jasmine,Istanbul,我正忙于单元测试。我有一个有棱角的材料 我尝试测试这两个功能: openEcheqSelectorDialog() { this.dialog.open(EcheqSelectorComponent, { width: '600px', maxHeight: 'calc(100vh - 2em)', data: { participant: this.participant } }); } openSche

我正忙于单元测试。我有一个有棱角的材料

我尝试测试这两个功能:

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
      }
    });
  }
这是完整的组件:


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
      }
    });
  }
}


但如果我在单元测试中这样做:


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.component';
import { RouterTestingModule } from '@angular/router/testing';

describe('DetailComponent', () => {

  let component: 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 }
      ]
    }).compileComponents().then( () => {
      fixture = TestBed.createComponent(DetailComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    });
  }));

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

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

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

});



从'@angular/core/testing'导入{async,TestBed,ComponentFixture};
从“../../participant.module”导入{ParticipantModule};
从'@angular/router'导入{ActivatedRoute};
从'src/app/shared/stubs/PARTICIPANT INFO DTO.stub'导入{PARTICIPANT_INFO_DTO};
从“@angular/material/dialog”导入{MatDialog};
从'src/app/shared/stubs/i18n stub'导入{I18nStub};
从'@ngx translate/I18n polyfill'导入{I18n};
从“./detail.component”导入{DetailComponent};
从“@angular/router/testing”导入{RouterTestingModule};
描述('DetailComponent',()=>{
let组件:DetailComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
进口:[
参与模块,
路由测试模块
],
供应商:[
MatDialog,
{提供:ActivatedRoute,useValue:{
快照:{
数据:{
参与者:参与者信息[0]
}
}
}},
{提供:I18n,使用值:I18nStub}
]
}).compileComponents()。然后(()=>{
fixture=TestBed.createComponent(DetailComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
}));
它('应该创建DetailComponent',()=>{
fixture.detectChanges();
expect(component.toBeTruthy();
});
它('应在MatDialog中打开ECHEQSELECTOR组件',()=>{
component.openecheQSelectrorDialog();
});
它('应该在MatDialog中打开SchemaSelectorDialog',()=>{
openSchemaSelectorDialog();
});
});
然后在代码中覆盖茉莉花业力。一切似乎都被覆盖了——上面说是100%。但是我认为这不是进行单元测试的正确方法

所以我的问题是:答案正确吗

或者我需要改进什么

多谢各位

这是模板:

<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>


参与者-{Participant.fullName}
行动
发送电子邮件
发送模式
概述
埃奇
模式
QR码扫描

我可以给你一些提示来处理这个问题。您需要创建一个
spy
,并在其上放置
expect
。比如:

将对话服务公开,以便您可以轻松地对其进行监视

规格ts

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

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


让我知道这是否对您有效,或者您是否有错误。

有人有什么建议吗?谢谢,您没有测试第二个和第三个案例。你一定有所期待。谢谢你,维韦克。我添加了模板。因为它是通过点击按钮来工作的。那么,是否有必要包括一个测试,它将与一个按钮点击工作?覆盖率现在是100%。但你有什么建议?感谢you@savantCodeEngineer:单元测试是关于测试
组件的完整性,而不是测试它
如何与其他组件交互,这就是我们试图模拟外部事物的原因。在这种情况下,当收集
btn
时,组件有打开
MatDialog
的行为。所以,如果这一特性发生了变化,而您的测试没有覆盖它,那么这就不是一个很好的覆盖范围。因此,在单元测试中检查这一点很好。因此,尝试测试一些重要的HTML
DOM
元素的行为。有时这可能不会增加代码覆盖率,但单元测试的目的是确保组件的特性不会在不知不觉中发生更改。我已经为Angular写了一系列文章(在本页底部),因为这样的文章在互联网上很难找到。我正在我的组件中使用keyvalue管道,所以在测试对话框时,我发现找不到keyvalue管道错误,我已从angular/common导入.spec文件中的keyvalue管道,但它不起作用。有什么想法吗?@Shweta:我能看看代码吗。
  it('should open the EcheqSelectorComponent in a MatDialog', () => {
    spyOn(component.dialog,'open').and.callThrough();
    component.openEcheqSelectorDialog();
    expect(component.dialog.open).toHaveBeenCalledWith(EcheqSelectorComponent, {
      width: '600px',
      maxHeight: 'calc(100vh - 2em)',
      data: {
        participant: component.participant
      }
    });
  });

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