预期的间谍“服务方法”已被调用 -角度10

问题描述

我正在用Angular编写组件单元测试用例,但不确定在哪里做错了。在较早的时候,我已经编写了类似的测试用例,但是这个用例正在使我大吃一惊。

请在此处检查代码

组件代码

ngOnInit(): void {
    this.callFavoriteProjects();
  }

  /**
   * @description To fetch all the favorites projects
   */
  public callFavoriteProjects() {
    this.loadingService.show('loading-favorites');
    this.subscriptions[this.subscriptions.length] = this.projectsFavoriteService.getAllUserFavoriteProjects()
      .subscribe((data) => {
        this.favoriteProjectsList = data;
        this.filteredProjectList = data;
        this.loadingService.hide('loading-favorites');
      },(error) => {
          this.toastrService.error('','There is an error while processing the favorite projects!',{
            timeOut: 3000,progressBar: true,progressAnimation: 'increasing',});
          this.loadingService.hide('loading-favorites');
        }
      );
  }

茉莉花测试用例代码

describe('FavoriteProjectsComponent',() => {
  let component: FavoriteProjectsComponent;
  let fixture: ComponentFixture<FavoriteProjectsComponent>;
  let projectsFavoriteService: ProjectsFavoriteService;

  beforeEach(async(() => {
    Testbed.configureTestingModule({
      imports: [
        HttpClientTestingModule,RouterTestingModule,MaterialModule,ToastrModule.forRoot()
      ],declarations: [ FavoriteProjectsComponent ],schemas: [CUSTOM_ELEMENTS_SCHEMA],providers: [
        { provide: NgxSpinnerService,useClass: NgxSpinnerServiceStub },{ provide: ToastrService,useClass: ToastrServiceStub },{ provide: ProjectsHelperService,useClass: ProjectsHelperServiceStub },{ provide: ProjectsFavoriteService,useClass: ProjectsFavoriteServiceStub }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    projectsFavoriteService = Testbed.inject(ProjectsFavoriteService);
  });

  beforeEach(() => {
    fixture = Testbed.createComponent(FavoriteProjectsComponent);
    component = fixture.componentInstance;
    // fixture.detectChanges();
  });

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


  describe('method: ngOnInit should ',() => {
    it('call callFavoriteProjects,projectsFavoriteService.getAllUserFavoriteProjects() and return an Observable<any>',() => {
      spyOn(projectsFavoriteService,'getAllUserFavoriteProjects').and.returnValue(observableOf([]));
      spyOn(component,'callFavoriteProjects');
      component.ngOnInit();
      expect(component.callFavoriteProjects).toHaveBeenCalled();
      expect(projectsFavoriteService.getAllUserFavoriteProjects).toHaveBeenCalled();
    });

    it('call callFavoriteProjects,projectsFavoriteService.getAllUserFavoriteProjects() but throw Observable error','getAllUserFavoriteProjects').and.returnValue(throwError({ message: 'Error Message' }));
      spyOn(component,'callFavoriteProjects');
      component.ngOnInit();
      expect(component.callFavoriteProjects).toHaveBeenCalled();
      expect(projectsFavoriteService.getAllUserFavoriteProjects).toHaveBeenCalled();
    });

  });

});

项目收藏夹存根文件

import { of as observableOf } from 'rxjs';

export class ProjectsFavoriteServiceStub {

  getAllUserFavoriteProjects() {
    return observableOf([]);
  }
    
}

因此,如果ngOnInit均失败,则这两个测试用例均会出现。我也通过在调用ngOnInit()之后在每个测试用例中将它放在beforeEach plus中,来尝试了fix.detectChanges()。

我没有走错的地方。请帮忙。预先感谢。

解决方法

问题是spyOn(component,'callFavoriteProjects')。当您执行此操作时,我们将丢失有关callFavoriteProjects的实现详细信息,其中该方法/函数将仅返回未定义,并且我们仅知道是否已调用它。我们必须编写.and.callTrough才能真正调用此函数,而不仅仅是监视它是否被调用。

我已经注释了需要更改的行。

describe('method: ngOnInit should ',() => {
    it('call callFavoriteProjects,projectsFavoriteService.getAllUserFavoriteProjects() and return an Observable<any>',() => {
      spyOn(projectsFavoriteService,'getAllUserFavoriteProjects').and.returnValue(observableOf([]));
      spyOn(component,'callFavoriteProjects').and.callThrough(); // change this line
      component.ngOnInit();
      expect(component.callFavoriteProjects).toHaveBeenCalled();
      expect(projectsFavoriteService.getAllUserFavoriteProjects).toHaveBeenCalled();
    });

    it('call callFavoriteProjects,projectsFavoriteService.getAllUserFavoriteProjects() but throw Observable error','getAllUserFavoriteProjects').and.returnValue(throwError({ message: 'Error Message' }));
      spyOn(component,'callFavoriteProjects').and.callThrough(); // change this line
      component.ngOnInit();
      expect(component.callFavoriteProjects).toHaveBeenCalled();
      expect(projectsFavoriteService.getAllUserFavoriteProjects).toHaveBeenCalled();
    });

  });