首页 > 解决方案 > 预期的间谍“服务方法”已被调用。- 角 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');
        }
      );
  }

Jasmine 测试用例代码:

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', () => {
      spyOn(projectsFavoriteService, '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 中尝试了 fixture.detectChanges()。

我没有找到错误的方向。请帮忙。提前致谢。

标签: angularjasminekarma-jasminekarma-runnerkarma-coverage

解决方案


问题是spyOn(component, 'callFavoriteProjects')。当你这样做时,我们失去了关于这个方法/函数将在哪里返回 undefined 的实现细节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', () => {
      spyOn(projectsFavoriteService, '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();
    });

  });

推荐阅读