Jasmine 测试:需要 SPY 但出现函数错误

Jasmine test : Expected a SPY but got a Function error

我已经使用 Jasmine 为 angular 组件编写了一个测试并出现错误。我基本上想测试在调用 ngOnchanges 时是否调用了 loadPersonNotes

ComplianceNoteComponent should call getPersonNote FAILED
        Error: <toHaveBeenCalled> : Expected a spy, but got Function.
        Usage: expect(<spyObj>).toHaveBeenCalled()
            at <Jasmine>

我不确定它为什么抱怨

茉莉花测试

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { of, Observable } from 'rxjs';
import { configureTestSuite } from 'ng-bullet';
import { DxButtonModule } from 'devextreme-angular';
import { NgxPermissionsModule } from 'ngx-permissions';

import { SharedFontAwesomeModule } from '../../../../shared/shared-font-awesome.module';
import { UserService } from '../../../../shared/services/user.service';
import { ComplianceNoteComponent } from './compliance-note.component';
import { IPersonNote } from '../../../../shared/models/IPersonNote';
import { IUser } from '../../../../shared/models/IUser';
import { nameof } from '../../../../shared/helpers/nameof';



describe('ComplianceNoteComponent', () => {
  let component: ComplianceNoteComponent;
  let fixture: ComponentFixture<ComplianceNoteComponent>;

  const mockPersonNote = <IPersonNote>{
    authorId : 12,
    id : 1,
    personId : 101,
    note : 'This is a test note ',
    authorName: 'xys',
    createdBy: 'ABC',
    createdDate : new Date()
  };

  const mockUserService: UserService = <UserService>{
    getCurrentUser() {
      return <IUser>{ id: 1 };
    },
    getPersonNote(id: 1) { 
      return of ({}); }
  };

  configureTestSuite((() => {
    TestBed.configureTestingModule({
      imports: [DxButtonModule, SharedFontAwesomeModule, NgxPermissionsModule.forRoot()],
      declarations: [ComplianceNoteComponent],
      providers: [
        { provide: UserService, useValue: mockUserService }
      ]
    });
  }));

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ ComplianceNoteComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(ComplianceNoteComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('should call getPersonNote', () => {
    spyOn(mockUserService, 'getPersonNote').and.returnValue(of(mockPersonNote)).and.callThrough();
    component.ngOnChanges();
    expect(component.loadPersonNotes).toHaveBeenCalled();
  });

});

组件

import { UserService } from 'src/app/shared/services/user.service';
import { IPersonNote } from 'src/app/shared/models/IPersonNote';

@Component({
  selector: 'app-compliance-note',
  templateUrl: './compliance-note.component.html',
  styleUrls: ['./compliance-note.component.scss']
})
export class ComplianceNoteComponent implements OnChanges {
  @Input() id: number;
  public personNotes: IPersonNote;
  public isCurrentUser = false;

  constructor(  private userService: UserService) { }

  ngOnChanges() {
    this.loadPersonNotes();
  }


  loadPersonNotes() {
    this.isCurrentUser = this.id !== this.userService.getCurrentUser().id;
    this.userService.getPersonNote(this.id).subscribe((x: IPersonNote) => {
      this.personNotes = x;
    });
  }

}

用户服务

    public getPersonNote = (id: number): Observable<IPersonNote> =>
    this.http.get<IPersonNote>(`${this.baseUrl}person-note/${id}`)  


export interface IPersonNote {
    id: number;
    personId: number;
    note: string;
    authorId: number;
    authorName: string;
    createdBy: string;
    createdDate: Date;
}   

问题是下面的 expect 需要一个 spy 但你提供了 class 方法 component.loadPersonNotes.

expect(component.loadPersonNotes).toHaveBeenCalled();

要使其正常工作,您需要在调用 component.ngOnChanges.

之前在 component.loadPersonNotes 方法上创建一个间谍程序
spyOn(component, 'loadPersonNotes');
component.ngOnChanges();
expect(component.loadPersonNotes).toHaveBeenCalled();

根据测试说明,您想要验证是否调用了 UserService 中的 getPersonNote。因此,您可能需要重新考虑您的 expect