Angular 测试 - 未调用 createSpyObj 方法

Angular Testing - createSpyObj method not called

我有一个 Angular 组件和一项服务。在组件中,我有一个方法调用服务的一个方法。在组件测试中,我尝试为服务创建一个模拟,然后当我调用组件的方法时,我想检查是否从组件调用了服务方法。

组件:

export class TestComponent {

  constructor(private testService: TestService) {}

  edit(): void {
    this.testService.getCase('id').subscribe(console.log);
  }
}

服务:

@Injectable({
  providedIn: 'root'
})
export class TestService {

  constructor(
    private http: HttpClient,
  ) { }

  getCase(id: string): Observable<any> {
    return this.http.get<any>(`url`);
  }
}

测试:

describe('TestComponent', () => {
  let component: TestComponent;
  let fixture: ComponentFixture<TestComponent>;
  const testServiceMock = jasmine.createSpyObj('TestService', ['getCase']);
  
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ TestComponent ],
      providers: [
        { provide: TestService, useValue: testServiceMock },
      ]
    })
      .compileComponents();
  });

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

  it('expect service has been called', () => {
    spyOn(component, 'edit');
    component.edit();
    expect(component.edit).toHaveBeenCalledTimes(1);
    expect(testServiceMock.getCase).toHaveBeenCalled();
  });
});

这条线经常失败:
expect(testServiceMock.getCase).toHaveBeenCalled();

TestComponent expect service has been called FAILED Error: Expected spy TestService.getCase to have been called.

您需要将调用委托给实际实现:

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

https://jasmine.github.io/2.0/introduction#section-Spies:_%3Ccode%3Eand.callThrough%3C/code%3E

由于 edit 方法是一个间谍,实际的实现永远不会被调用,所以 getCase 间谍也永远不会被调用。为了解决这个问题,请使用 edit 方法 spy 和 callThrough()。这会强制调用实际实现。

spyOn(component,'edit').and.callThrough()