【问题标题】:Expected function is a called but none of the functions inside of it are never called预期的函数是被调用的,但它里面的任何函数都不会被调用
【发布时间】:2021-06-14 21:39:04
【问题描述】:

所以我目前正在使用 Jasmine 和 Karma 对 Angular 应用程序进行一些单元测试。我的单元测试有问题,必须打开一个模式,更改表单的某些值并保存它。一切都做得很好,直到它达到我的模态服务的open()的承诺并调用saveAttribute()函数。

expect 似乎已成功调用 saveAttribute(),但其中的任何函数都从未被调用,即使是 hasValidRegex() 函数,尽管它是 saveAttribute() 函数中调用的第一个函数。我还尝试在saveAttribute() 函数的开头使用控制台日志,但它永远不会到达它并且除了函数开始成功调用之外什么都不打印。我错过了什么吗?

.spec 文件

it('should save edited values in an selected attribute', fakeAsync(() => {
    const mockOpenModalResult = {
      result: new Promise((resolve, reject) => resolve('Save'))
    };
    spyOn(ngbModal, 'open').and.returnValue(mockOpenModalResult);
    spyOn(component, 'saveAttribute');
    spyOn(component, 'hasValidRegex').and.returnValue(true);
    spyOn(siteService, 'saveRequestTypeAttribute').and.returnValue(1155);
    spyOn(component, 'updateSiteTreeView');
    spyOn(component, 'clearFields');
    
    component.openModalInternal(mockAttributeRootNode, mockDetectChanges);
    flush();
    
    expect(component.saveAttribute).toHaveBeenCalledWith(mockAttributeRootNode, mockDetectChanges);
    expect(component.hasValidRegex).toHaveBeenCalled();


    expect(siteService.saveRequestTypeAttribute).toHaveBeenCalledWith(mockRequestTypeAttribute);
expect(component.updateSiteTreeView).toHaveBeenCalledWith(mockRequestTypeAttribute);
    expect(component.clearFields).toHaveBeenCalled();

  }));

Component.ts

openModalInternal(attributeRootNode: SiteTreeNode, detectChanges: Function) {
    this.title = this.editMode ? 'Edit' : 'Add';
    const ngbModalOptions: NgbModalOptions = {
      ariaLabelledBy: this.title,
      backdrop: 'static',
      scrollable: true,
      size: 'xl',
      centered: true,
      keyboard: false
    };
    this.modalService.open(this.requestTypeAttributeTypeModal, ngbModalOptions).result.then(result => {
      if (result === 'Save') {
        console.log('test reaches this part of the code and calls saveAttributes successfully')
        this.saveAttribute(attributeRootNode, detectChanges);
      } else if (result === 'Remove') {
        this.removeAttribute(attributeRootNode, detectChanges);
      } else {
        this.clearFields();
      }
    });
  }
  
  
  saveAttribute(attributeRootNode: SiteTreeNode, detectChanges: Function) {
    if (!this.hasValidRegex()) {
      return;
    }
    const locationId: number = this.storageService.getLocationId();
    const myObjType: item = {
      // ...
    };
    this.siteService.saveRequestTypeAttribute(item).subscribe(id => {
      item.AttributeId = id;
      this.alertMessageService.setSuccessMessage([SuccessMessage.SuccessMessage]);
      this.updateSiteTreeView(attributeRootNode, detectChanges);
    });
    this.clearFields();
  }

错误:

注意:由于披露问题,无法向您显示模拟数据。但我认为模拟数据不会导致这种行为

【问题讨论】:

    标签: angular typescript unit-testing jasmine karma-jasmine


    【解决方案1】:

    我想我知道这个问题。问题是这样的:

    spyOn(component, 'saveAttribute');
    

    当你spyOn一个方法时,你会丢失它的实现细节,你只能看到它是否被调用或被调用了多少次。要保留实现细节,您必须使用.and.callThrough() 在每次调用该函数时实际调用它。

    将行改为:

    spyOn(component, 'saveAttribute').and.callThrough();
    

    测试应该会通过。

    【讨论】:

    • 非常感谢!它对我有用。我对spyOn的实际含义感到困惑。
    猜你喜欢
    • 2019-03-28
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2021-03-06
    • 2020-02-10
    • 2018-12-27
    • 2018-05-25
    • 2021-10-11
    相关资源
    最近更新 更多