预期函数被调用,但其中 none 的函数从未被调用

Expected function is a called but none of the functions inside of it are never called

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

expects 似乎被调用 saveAttribute() 成功,但是其中的 none 函数从未被调用,即使是 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();
  }

错误:

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

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

spyOn(component, 'saveAttribute');

当您 spyOn 一个方法时,您将丢失其实现细节,您只能查看它是否被调用或被调用了多少次。为了仍然有实现细节,你必须使用 .and.callThrough() 在每次调用时实际调用该函数。

将行更改为:

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

测试应该会通过。