模拟 Angular Material 对话框 afterClosed() 进行单元测试 [英] Mocking Angular Material Dialog afterClosed() for unit test

查看:21
本文介绍了模拟 Angular Material 对话框 afterClosed() 进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下功能打开我的垫子对话框:

accept() {让 dialogRef = this.dialog.open(AcceptDialogComponent, {数据: {已接受:假}})dialogRef.afterClosed().subscribe(result => {控制台日志(结果);if (result.hasAccepted === true) {this.leadService.acceptLead(this.holdingAccountId, this.lead.id).管道(takeUntil(this.onDestroy$)).subscribe(acceptLeadRes => {控制台日志(acceptLeadRes);this.leadService.updateLeadAction('accept');},(错误:HttpErrorResponse)=>{控制台日志(错误);this.router.navigate(['/error']);});}});}

我正在尝试为这个函数编写一个测试,它只是触发 afterClosed() 以便我可以检查是否调用了进行后端调用的服务方法.

component.spec.ts (beforeEach Testbed 创建)

beforeEach(async (() => {TestBed.configureTestingModule({声明:[LeadCardComponent,AcceptDialogComponent],进口:[所需的测试模块,JwtModule.forRoot({配置:{tokenGetter: () =>{返回 '​​';}}})],供应商: [应用洞察服务,JwtHelperService,//{ 提供:LeadsService,useValue:leadServiceSpy }],}),TestBed.overrideModule(BrowserDynamicTestingModule, {放: {entryComponents:[AcceptDialogComponent]}});TestBed.compileComponents();}));

component.spec.ts(测试)

it('从 AcceptLeadDialog 返回且 hasAccepted 等于 true 应该调用 acceptLead 端点', () => {让 matDiaglogref = dialog.open(AcceptDialogComponent, {数据: {已接受:假}});spyOn(matDiaglogref, 'afterClosed').and.callThrough().and.returnValue({已接受:真});spyOn(leadService, 'acceptLead').and.callThrough();component.acceptLead();夹具.detectChanges();matDiaglogref.close();夹具.detectChanges();期望(leadService.acceptLead).toHaveBeenCalled();});

测试当前失败,并显示预期的间谍 acceptLead 已被调用".我无法理解如何测试该函数并执行某种模拟 MatDialogRef 以便我可以检查我的测试条件是否通过.

任何帮助/建议将不胜感激

更新从接受的答案实施的工作测试

it('从 AcceptLeadDialog 返回且 hasAccepted 等于 true 应该调用 acceptLead 端点', () => {spyOn(component.dialog, '打开').和.returnValue({afterClosed: () =>的({已接受:真})});spyOn(leadService, 'acceptLead').and.callThrough();component.acceptLead();期望(component.dialog).toBeDefined();期望(leadService.acceptLead).toHaveBeenCalled();});

解决方案

你可以这样测试 Angular Material Dialog 的 afterClosed 方法:

  1. import { of } from 'rxjs';
  2. 监视对话框并为 afterClosed() 方法返回一个 observable

spyOn(component.dialog, 'open').和.returnValue({afterClosed: () => of(true)});

基本上, dialogRef 的 afterClosed() 期待一个 Observable.因此,我们监视组件的对话框打开方法,并使用 rxjs 中的 of 运算符为 afterClosed() 方法返回一个 Observable.

然后,您可以将 returnValue 中的 of(true) 替换为您在 afterClosed()afterClosed() 中发送的数据主组件中的对话框.

I am opening my mat-dialog with the following function:

accept() {
  let dialogRef = this.dialog.open(AcceptDialogComponent, {
    data: {
      hasAccepted: false
    }
  })
  dialogRef.afterClosed().subscribe(result => {
    console.log(result);
    if (result.hasAccepted === true) {
      this.leadService.acceptLead(this.holdingAccountId, this.lead.id)
        .pipe(
          takeUntil(this.onDestroy$)
        )
        .subscribe(acceptLeadRes => {
            console.log(acceptLeadRes);
            this.leadService.updateLeadAction('accept');
          },
          (err: HttpErrorResponse) => {
            console.log(err);
            this.router.navigate(['/error']);
          });
    }
  });
}

I am attempting to write a test for this function that simply fires the afterClosed() so that I can check if my service method that makes a backend call is called.

component.spec.ts (beforeEach Testbed creation)

beforeEach(async (() => {
  TestBed.configureTestingModule({
      declarations: [LeadCardComponent, AcceptDialogComponent],
      imports: [
        requiredTestModules,
        JwtModule.forRoot({
          config: {
            tokenGetter: () => {
              return '';
            }
          }
        })
      ],
      providers: [
        ApplicationInsightsService,
        JwtHelperService,
        // { provide: LeadsService, useValue: leadServiceSpy }
      ],
    }),

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

component.spec.ts (test)

it('Return from AcceptLeadDialog with hasAccepted equals true should call acceptLead endpoint', () => {
  let matDiaglogref = dialog.open(AcceptDialogComponent, {
    data: {
      hasAccepted: false
    }
  });
  spyOn(matDiaglogref, 'afterClosed').and.callThrough().and.returnValue({
    hasAccepted: true
  });
  spyOn(leadService, 'acceptLead').and.callThrough();
  component.acceptLead();
  fixture.detectChanges();
  matDiaglogref.close();
  fixture.detectChanges();

  expect(leadService.acceptLead).toHaveBeenCalled();
});

The test currently fails with a "Expected spy acceptLead to have been called." I am failing on understanding how to test the function and execute some sort of mock MatDialogRef so that I can check if the conditions of my test pass.

Any help/suggestions would be much appreciated

Update Working Test implemented from Accepted Answer

it('Return from AcceptLeadDialog with hasAccepted equals true should call acceptLead endpoint', () => {
  spyOn(component.dialog, 'open')
    .and
    .returnValue({
      afterClosed: () => of({
        hasAccepted: true
      })
    });
  spyOn(leadService, 'acceptLead').and.callThrough();
  component.acceptLead();
  expect(component.dialog).toBeDefined();
  expect(leadService.acceptLead).toHaveBeenCalled();
});

解决方案

You can test Angular Material Dialog's afterClosed method this way:

  1. import { of } from 'rxjs';
  2. spy on the dialog and return an observable for the afterClosed() method

spyOn(component.dialog, 'open')
     .and
     .returnValue({afterClosed: () => of(true)});

Basically, the afterClosed() of the dialogRef is expecting an Observable. So we spy on the component's dialog open method and return an Observable for the afterClosed() method by using the of operator from rxjs.

You can then replace the of(true) from the returnValue with your own data what you are sending in the afterClosed() of the dialog in the main component.

这篇关于模拟 Angular Material 对话框 afterClosed() 进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆